/* Get the additional information for a CIDFontType 0 or 2 CIDFont. */ int cid_font_data_param(os_ptr op, gs_font_cid_data *pdata, ref *pGlyphDirectory) { int code; ref *pgdir; check_type(*op, t_dictionary); if ((code = cid_font_system_info_param(&pdata->CIDSystemInfo, op)) < 0 || (code = dict_int_param(op, "CIDCount", 0, max_int, -1, &pdata->CIDCount)) < 0 ) return code; /* * If the font doesn't have a GlyphDirectory, GDBytes is required. * If it does have a GlyphDirectory, GDBytes may still be needed for * CIDMap: it's up to the client to check this. */ if (dict_find_string(op, "GlyphDirectory", &pgdir) <= 0) { /* Standard CIDFont, require GDBytes. */ make_null(pGlyphDirectory); return dict_int_param(op, "GDBytes", 1, MAX_GDBytes, 0, &pdata->GDBytes); } if (r_has_type(pgdir, t_dictionary) || r_is_array(pgdir)) { /* GlyphDirectory, GDBytes is optional. */ *pGlyphDirectory = *pgdir; code = dict_int_param(op, "GDBytes", 0, MAX_GDBytes, 0, &pdata->GDBytes); return code; } else { return_error(e_typecheck); } }
static int z_imscale_d(i_ctx_t * i_ctx_p) { os_ptr op = osp; /* i_ctx_p->op_stack.stack.p defined in osstack.h */ int width, height; stream_imscale_state state; /* extract the key from the parameter dictionary */ check_type(*op, t_dictionary); check_dict_read(*op); if (dict_int_param(op, "Width", 0, 1<<24, -1, &width) < 0) return_error(gs_error_rangecheck); if (dict_int_param(op, "Height", 0, 1<<24, -1, &height) < 0) return_error(gs_error_rangecheck); state.params.spp_decode = 1; state.params.spp_interp = 1; state.params.BitsPerComponentIn = 1; state.params.MaxValueIn = 1; state.params.WidthIn = width; state.params.HeightIn = height; state.params.BitsPerComponentOut = 1; state.params.MaxValueOut = 1; state.params.WidthOut = width << 2; state.params.HeightOut = height << 2; /* we pass npop=0, since we've no arguments left to consume */ /* we pass 0 instead of the usual rspace(sop) will allocate storage for filter state from the same memory pool as the stream it's coding. this causes no trouble because we maintain no pointers */ return filter_read(i_ctx_p, 0, &s_imscale_template, (stream_state *) & state, 0); }
/* 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)); }
/* <dict> .image3 - */ private int zimage3(i_ctx_t *i_ctx_p) { os_ptr op = osp; gs_image3_t image; int interleave_type; ref *pDataDict; ref *pMaskDict; image_params ip_data, ip_mask; int ignored; int code, mcode; check_type(*op, t_dictionary); check_dict_read(*op); if ((code = dict_int_param(op, "InterleaveType", 1, 3, -1, &interleave_type)) < 0 ) return code; gs_image3_t_init(&image, NULL, interleave_type); if (dict_find_string(op, "DataDict", &pDataDict) <= 0 || dict_find_string(op, "MaskDict", &pMaskDict) <= 0 ) return_error(e_rangecheck); if ((code = pixel_image_params(i_ctx_p, pDataDict, (gs_pixel_image_t *)&image, &ip_data, 12, false)) < 0 || (mcode = code = data_image_params(imemory, pMaskDict, &image.MaskDict, &ip_mask, false, 1, 12, false)) < 0 || (code = dict_int_param(pDataDict, "ImageType", 1, 1, 0, &ignored)) < 0 || (code = dict_int_param(pMaskDict, "ImageType", 1, 1, 0, &ignored)) < 0 ) return code; /* * MaskDict must have a DataSource iff InterleaveType == 3. */ if ((ip_data.MultipleDataSources && interleave_type != 3) || ip_mask.MultipleDataSources || mcode != (image.InterleaveType != 3) ) return_error(e_rangecheck); if (image.InterleaveType == 3) { /* Insert the mask DataSource before the data DataSources. */ memmove(&ip_data.DataSource[1], &ip_data.DataSource[0], (countof(ip_data.DataSource) - 1) * sizeof(ip_data.DataSource[0])); ip_data.DataSource[0] = ip_mask.DataSource[0]; } return zimage_setup(i_ctx_p, (gs_pixel_image_t *)&image, &ip_data.DataSource[0], image.CombineWithColor, 1); }
/* BitsPerSample. */ static int dict_threshold2_params(const ref * pdict, gs_threshold2_halftone * ptp, ref * ptproc, gs_memory_t *mem) { ref *tstring; int code = dict_threshold_common_params(pdict, (gs_threshold_halftone_common *)ptp, &tstring, ptproc); int bps; uint size; int cw2, ch2; if (code < 0 || (code = cw2 = dict_int_param(pdict, "Width2", 0, 0x7fff, 0, &ptp->width2)) < 0 || (code = ch2 = dict_int_param(pdict, "Height2", 0, 0x7fff, 0, &ptp->height2)) < 0 || (code = dict_int_param(pdict, "BitsPerSample", 8, 16, -1, &bps)) < 0 ) return code; if ((bps != 8 && bps != 16) || cw2 != ch2 || (!cw2 && (ptp->width2 == 0 || ptp->height2 == 0)) ) return_error(e_rangecheck); ptp->bytes_per_sample = bps / 8; switch (r_type(tstring)) { case t_string: size = r_size(tstring); gs_bytestring_from_string(&ptp->thresholds, tstring->value.const_bytes, size); break; case t_astruct: if (gs_object_type(mem, tstring->value.pstruct) != &st_bytes) return_error(e_typecheck); size = gs_object_size(mem, tstring->value.pstruct); gs_bytestring_from_bytes(&ptp->thresholds, r_ptr(tstring, byte), 0, size); break; default: return_error(e_typecheck); } check_read(*tstring); if (size != (ptp->width * ptp->height + ptp->width2 * ptp->height2) * ptp->bytes_per_sample) return_error(e_rangecheck); return 0; }
/* The caller guarantees that *op is a dictionary. */ int build_gs_outline_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font_base ** ppfont, font_type ftype, gs_memory_type_ptr_t pstype, const build_proc_refs * pbuild, build_font_options_t options, build_base_font_proc_t build_base_font) { int painttype; float strokewidth; gs_font_base *pfont; int code = dict_int_param(op, "PaintType", 0, 3, 0, &painttype); if (code < 0) return code; code = dict_float_param(op, "StrokeWidth", 0.0, &strokewidth); if (code < 0) return code; code = build_base_font(i_ctx_p, op, ppfont, ftype, pstype, pbuild, options); if (code != 0) return code; pfont = *ppfont; pfont->PaintType = painttype; pfont->StrokeWidth = strokewidth; return 0; }
/* Extract Width, Height, and TransferFunction from a dictionary. */ static int dict_threshold_common_params(const ref * pdict, gs_threshold_halftone_common * ptp, ref **pptstring, ref *ptproc) { int code; check_dict_read(*pdict); if ((code = dict_int_param(pdict, "Width", 1, 0x7fff, -1, &ptp->width)) < 0 || (code = dict_int_param(pdict, "Height", 1, 0x7fff, -1, &ptp->height)) < 0 || (code = dict_find_string(pdict, "Thresholds", pptstring)) <= 0 || (code = dict_proc_param(pdict, "TransferFunction", ptproc, false)) < 0 ) return (code < 0 ? code : e_undefined); ptp->transfer_closure.proc = 0; ptp->transfer_closure.data = 0; return code; }
/* Collect the BitsPerFlag parameter, if relevant. */ static int flag_bits_param(const ref * op, const gs_shading_mesh_params_t * params, int *pBitsPerFlag) { if (data_source_is_array(params->DataSource)) { *pBitsPerFlag = 0; return 0; } else { return dict_int_param(op, "BitsPerFlag", 2, 8, 0, pBitsPerFlag); } }
/* Common setup for encoding and decoding filters */ static int bwbs_setup(os_ptr op, stream_BWBS_state * pbwbss) { int code = dict_int_param(op, "BlockSize", 1, max_int / sizeof(int) - 10, 16384, &pbwbss->BlockSize); if (code < 0) return code; return 0; }
/* Get ColorRenderingType 1 parameters from the PostScript dictionary. */ static int zcrd1_params(os_ptr op, gs_cie_render * pcrd, ref_cie_render_procs * pcprocs, gs_memory_t * mem) { int code; int ignore; gx_color_lookup_table *const prtl = &pcrd->RenderTable.lookup; ref *pRT; if ((code = dict_int_param(op, "ColorRenderingType", 1, 1, 0, &ignore)) < 0 || (code = zcrd1_proc_params(mem, op, pcprocs)) < 0 || (code = dict_matrix3_param(mem, op, "MatrixLMN", &pcrd->MatrixLMN)) < 0 || (code = dict_range3_param(mem, op, "RangeLMN", &pcrd->RangeLMN)) < 0 || (code = dict_matrix3_param(mem, op, "MatrixABC", &pcrd->MatrixABC)) < 0 || (code = dict_range3_param(mem, op, "RangeABC", &pcrd->RangeABC)) < 0 || (code = cie_points_param(mem, op, &pcrd->points)) < 0 || (code = dict_matrix3_param(mem, op, "MatrixPQR", &pcrd->MatrixPQR)) < 0 || (code = dict_range3_param(mem,op, "RangePQR", &pcrd->RangePQR)) < 0 ) return code; if (dict_find_string(op, "RenderTable", &pRT) > 0) { const ref *prte = pRT->value.const_refs; /* Finish unpacking and checking the RenderTable parameter. */ check_type_only(prte[4], t_integer); if (!(prte[4].value.intval == 3 || prte[4].value.intval == 4)) return_error(e_rangecheck); prtl->n = 3; prtl->m = prte[4].value.intval; if (r_size(pRT) != prtl->m + 5) return_error(e_rangecheck); code = cie_table_param(pRT, prtl, mem); if (code < 0) return code; } else { prtl->table = 0; } pcrd->EncodeLMN = Encode_default; pcrd->EncodeABC = Encode_default; pcrd->TransformPQR = TransformPQR_default; pcrd->RenderTable.T = RenderTableT_default; return 0; }
/* Build a ShadingType 5 (Lattice-form Gouraud triangle mesh) shading. */ static int build_shading_5(i_ctx_t *i_ctx_p, const ref * op, const gs_shading_params_t * pcommon, gs_shading_t ** ppsh, gs_memory_t *mem) { gs_shading_LfGt_params_t params; int code; *(gs_shading_params_t *)¶ms = *pcommon; if ((code = build_mesh_shading(i_ctx_p, op, (gs_shading_mesh_params_t *)¶ms, ¶ms.Decode, ¶ms.Function, mem)) < 0 || (code = check_indexed_vs_function(i_ctx_p, op, params.ColorSpace, params.Function)) < 0 || (code = dict_int_param(op, "VerticesPerRow", 2, max_int, 0, ¶ms.VerticesPerRow)) < 0 || (code = gs_shading_LfGt_init(ppsh, ¶ms, mem)) < 0 ) { gs_free_object(mem, params.Function, "Function"); gs_free_object(mem, params.Decode, "Decode"); } return code; }
/* Get the information from a CIDSystemInfo dictionary. */ int cid_system_info_param(gs_cid_system_info_t *pcidsi, const ref *prcidsi) { ref *pregistry; ref *pordering; int code; if (!r_has_type(prcidsi, t_dictionary)) return_error(e_typecheck); if (dict_find_string(prcidsi, "Registry", &pregistry) <= 0 || dict_find_string(prcidsi, "Ordering", &pordering) <= 0 ) return_error(e_rangecheck); check_read_type_only(*pregistry, t_string); check_read_type_only(*pordering, t_string); pcidsi->Registry.data = pregistry->value.const_bytes; pcidsi->Registry.size = r_size(pregistry); pcidsi->Ordering.data = pordering->value.const_bytes; pcidsi->Ordering.size = r_size(pordering); code = dict_int_param(prcidsi, "Supplement", 0, max_int, -1, &pcidsi->Supplement); return (code < 0 ? code : 0); }
/* of the same length as filters, or null. */ static int zrsdparams(i_ctx_t *i_ctx_p) { os_ptr op = osp; ref *pFilter; ref *pDecodeParms; int Intent = 0; bool AsyncRead; ref empty_array, filter1_array, parms1_array; uint i; int code; make_empty_array(&empty_array, a_readonly); if (dict_find_string(op, "Filter", &pFilter) > 0) { if (!r_is_array(pFilter)) { if (!r_has_type(pFilter, t_name)) return_error(e_typecheck); make_array(&filter1_array, a_readonly, 1, pFilter); pFilter = &filter1_array; } } else pFilter = &empty_array; /* If Filter is undefined, ignore DecodeParms. */ if (pFilter != &empty_array && dict_find_string(op, "DecodeParms", &pDecodeParms) > 0 ) { if (pFilter == &filter1_array) { make_array(&parms1_array, a_readonly, 1, pDecodeParms); pDecodeParms = &parms1_array; } else if (!r_is_array(pDecodeParms)) return_error(e_typecheck); else if (r_size(pFilter) != r_size(pDecodeParms)) return_error(e_rangecheck); } else pDecodeParms = 0; for (i = 0; i < r_size(pFilter); ++i) { ref f, fname, dp; array_get(imemory, pFilter, (long)i, &f); if (!r_has_type(&f, t_name)) return_error(e_typecheck); name_string_ref(imemory, &f, &fname); if (r_size(&fname) < 6 || memcmp(fname.value.bytes + r_size(&fname) - 6, "Decode", 6) ) return_error(e_rangecheck); if (pDecodeParms) { array_get(imemory, pDecodeParms, (long)i, &dp); if (!(r_has_type(&dp, t_dictionary) || r_has_type(&dp, t_null))) return_error(e_typecheck); } } code = dict_int_param(op, "Intent", 0, 3, 0, &Intent); if (code < 0 && code != e_rangecheck) /* out-of-range int is ok, use 0 */ return code; if ((code = dict_bool_param(op, "AsyncRead", false, &AsyncRead)) < 0 ) return code; push(1); op[-1] = *pFilter; if (pDecodeParms) *op = *pDecodeParms; else make_null(op); return 0; }
static int zmatchmedia(i_ctx_t *i_ctx_p) { os_ptr op = osp; os_ptr preq = op - 3; os_ptr pattr = op - 2; os_ptr ppol = op - 1; os_ptr pkeys = op; /* *const */ int policy_default; float best_mismatch = (float)max_long; /* adhoc */ float mepos_penalty; float mbest = best_mismatch; match_record_t match; ref no_priority; ref *ppriority; int mepos, orient; bool roll; int code; int ai; struct mkd_ { ref key, dict; } aelt; if (r_has_type(pattr, t_null)) { check_op(4); make_null(op - 3); make_true(op - 2); pop(2); return 0; } check_type(*preq, t_dictionary); check_dict_read(*preq); check_type(*pattr, t_dictionary); check_dict_read(*pattr); check_type(*ppol, t_dictionary); check_dict_read(*ppol); check_array(*pkeys); check_read(*pkeys); switch (code = dict_int_null_param(preq, "MediaPosition", 0, 0x7fff, 0, &mepos)) { default: return code; case 2: case 1: mepos = -1; case 0:; } switch (code = dict_int_null_param(preq, "Orientation", 0, 3, 0, &orient)) { default: return code; case 2: case 1: orient = -1; case 0:; } code = dict_bool_param(preq, "RollFedMedia", false, &roll); if (code < 0) return code; code = dict_int_param(ppol, "PolicyNotFound", 0, 7, 0, &policy_default); if (code < 0) return code; if (dict_find_string(pattr, "Priority", &ppriority) > 0) { check_array_only(*ppriority); check_read(*ppriority); } else { make_empty_array(&no_priority, a_readonly); ppriority = &no_priority; } match.no_match_priority = r_size(ppriority); reset_match(&match); for (ai = dict_first(pattr); (ai = dict_next(pattr, ai, (ref * /*[2]*/)&aelt)) >= 0; ) { if (r_has_type(&aelt.dict, t_dictionary) && r_has_attr(dict_access_ref(&aelt.dict), a_read) && r_has_type(&aelt.key, t_integer) ) { bool match_all; uint ki, pi; code = dict_bool_param(&aelt.dict, "MatchAll", false, &match_all); if (code < 0) return code; for (ki = 0; ki < r_size(pkeys); ki++) { ref key; ref kstr; ref *prvalue; ref *pmvalue; ref *ppvalue; int policy; array_get(imemory, pkeys, ki, &key); if (dict_find(&aelt.dict, &key, &pmvalue) <= 0) continue; if (dict_find(preq, &key, &prvalue) <= 0 || r_has_type(prvalue, t_null) ) { if (match_all) goto no; else continue; } /* Look for the Policies entry for this key. */ if (dict_find(ppol, &key, &ppvalue) > 0) { check_type_only(*ppvalue, t_integer); policy = ppvalue->value.intval; } else policy = policy_default; /* * Match a requested attribute value with the attribute value in the * description of a medium. For all attributes except PageSize, * matching means equality. PageSize is special; see match_page_size * below. */ if (r_has_type(&key, t_name) && (name_string_ref(imemory, &key, &kstr), r_size(&kstr) == 8 && !memcmp(kstr.value.bytes, "PageSize", 8)) ) { gs_matrix ignore_mat; gs_point ignore_msize; if (zmatch_page_size(imemory, prvalue, pmvalue, policy, orient, roll, &best_mismatch, &ignore_mat, &ignore_msize) <= 0) goto no; } else if (!obj_eq(imemory, prvalue, pmvalue)) goto no; } mepos_penalty = (mepos < 0 || aelt.key.value.intval == mepos) ? 0 : .001; /* We have a match. Save the match in case no better match is found */ if (r_has_type(&match.match_key, t_null)) match.match_key = aelt.key; /* * If it is a better match than the current best it supersedes it * regardless of priority. If the match is the same, then update * to the current only if the key value is lower. */ if (best_mismatch + mepos_penalty <= mbest) { if (best_mismatch + mepos_penalty < mbest || (r_has_type(&match.match_key, t_integer) && match.match_key.value.intval > aelt.key.value.intval)) { reset_match(&match); match.match_key = aelt.key; mbest = best_mismatch + mepos_penalty; } } /* In case of a tie, see if the new match has priority. */ for (pi = match.priority; pi > 0;) { ref pri; pi--; array_get(imemory, ppriority, pi, &pri); if (obj_eq(imemory, &aelt.key, &pri)) { /* Yes, higher priority. */ match.best_key = aelt.key; match.priority = pi; break; } } no:; } } if (r_has_type(&match.match_key, t_null)) { make_false(op - 3); pop(3); } else { if (r_has_type(&match.best_key, t_null)) op[-3] = match.match_key; else op[-3] = match.best_key; make_true(op - 2); pop(2); } return 0; }
/* Extract and check the parameters for a gs_data_image_t. */ int data_image_params(const gs_memory_t *mem, const ref *op, gs_data_image_t *pim, image_params *pip, bool require_DataSource, int num_components, int max_bits_per_component, bool has_alpha) { int code; int decode_size; ref *pds; check_type(*op, t_dictionary); check_dict_read(*op); if ((code = dict_int_param(op, "Width", 0, max_int_in_fixed / 2, -1, &pim->Width)) < 0 || (code = dict_int_param(op, "Height", 0, max_int_in_fixed / 2, -1, &pim->Height)) < 0 || (code = dict_matrix_param(mem, op, "ImageMatrix", &pim->ImageMatrix)) < 0 || (code = dict_bool_param(op, "MultipleDataSources", false, &pip->MultipleDataSources)) < 0 || (code = dict_int_param(op, "BitsPerComponent", 1, max_bits_per_component, -1, &pim->BitsPerComponent)) < 0 || (code = decode_size = dict_floats_param(mem, op, "Decode", num_components * 2, &pim->Decode[0], NULL)) < 0 || (code = dict_bool_param(op, "Interpolate", false, &pim->Interpolate)) < 0 ) return code; pip->pDecode = &pim->Decode[0]; /* Extract and check the data sources. */ if ((code = dict_find_string(op, "DataSource", &pds)) <= 0) { if (require_DataSource) return (code < 0 ? code : gs_note_error(e_rangecheck)); return 1; /* no data source */ } if (pip->MultipleDataSources) { ref *ds = pip->DataSource; long i, n = num_components + (has_alpha ? 1 : 0); if (!r_is_array(pds)) return_error(e_typecheck); if (r_size(pds) != n) return_error(e_rangecheck); for (i = 0; i < n; ++i) array_get(mem, pds, i, &ds[i]); if (r_type(&ds[0]) == t_string) { /* We don't have a problem with the strings of different length * but Adobe does and CET tast 12-02.ps reports this as an error. */ if (has_alpha) n--; for (i = 1; i < n; ++i) { if (r_type(&ds[i]) == t_string && r_size(&ds[i]) != r_size(&ds[0])) { return_error(e_rangecheck); } } } } else pip->DataSource[0] = *pds; return 0; }
/* <string|name> <font_dict> .buildfont9 <string|name> <font> */ static int zbuildfont9(i_ctx_t *i_ctx_p) { os_ptr op = osp; build_proc_refs build; int code = build_proc_name_refs(imemory, &build, NULL, "%Type9BuildGlyph"); gs_font_cid_data common; ref GlyphDirectory, GlyphData, DataSource; ref *prfda, cfnstr; ref *pCIDFontName, CIDFontName; gs_font_type1 **FDArray; uint FDArray_size; int FDBytes; uint CIDMapOffset; gs_font_base *pfont; gs_font_cid0 *pfcid; uint i; /* * If the CIDFont's data have been loaded into VM, GlyphData will be * a string or an array of strings; if they are loaded incrementally * from a file, GlyphData will be an integer, and DataSource will be * a (reusable) stream. */ if (code < 0 || (code = cid_font_data_param(op, &common, &GlyphDirectory)) < 0 || (code = dict_find_string(op, "FDArray", &prfda)) < 0 || (code = dict_find_string(op, "CIDFontName", &pCIDFontName)) <= 0 || (code = dict_int_param(op, "FDBytes", 0, MAX_FDBytes, -1, &FDBytes)) < 0 ) return code; /* * Since build_gs_simple_font may resize the dictionary and cause * pointers to become invalid, save CIDFontName */ CIDFontName = *pCIDFontName; if (r_has_type(&GlyphDirectory, t_null)) { /* Standard CIDFont, require GlyphData and CIDMapOffset. */ ref *pGlyphData; if ((code = dict_find_string(op, "GlyphData", &pGlyphData)) < 0 || (code = dict_uint_param(op, "CIDMapOffset", 0, max_uint - 1, max_uint, &CIDMapOffset)) < 0) return code; GlyphData = *pGlyphData; if (r_has_type(&GlyphData, t_integer)) { ref *pds; stream *ignore_s; if ((code = dict_find_string(op, "DataSource", &pds)) < 0) return code; check_read_file(i_ctx_p, ignore_s, pds); DataSource = *pds; } else { if (!r_has_type(&GlyphData, t_string) && !r_is_array(&GlyphData)) return_error(e_typecheck); make_null(&DataSource); } } else { make_null(&GlyphData); make_null(&DataSource); CIDMapOffset = 0; } if (!r_is_array(prfda)) return_error(e_invalidfont); FDArray_size = r_size(prfda); if (FDArray_size == 0) return_error(e_invalidfont); FDArray = ialloc_struct_array(FDArray_size, gs_font_type1 *, &st_gs_font_type1_ptr_element, "buildfont9(FDarray)"); if (FDArray == 0) return_error(e_VMerror); memset(FDArray, 0, sizeof(gs_font_type1 *) * FDArray_size); for (i = 0; i < FDArray_size; ++i) { ref rfd; array_get(imemory, prfda, (long)i, &rfd); code = fd_array_element(i_ctx_p, &FDArray[i], &rfd); if (code < 0) goto fail; } code = build_gs_outline_font(i_ctx_p, op, &pfont, ft_CID_encrypted, &st_gs_font_cid0, &build, bf_Encoding_optional | bf_UniqueID_ignored, build_gs_simple_font); if (code < 0) goto fail; if (code == 1) { /* The font already has a FID, don't need to build it again. Release FDArray and return normally. fixme: FDArray fonts are thrown for garbager. We're not safe to build them after build_gs_simple_font(..., &pfont, ...), because a failure in building them would throw an underbuilt font with unclear consequences. */ ifree_object(FDArray, "buildfont9(FDarray)"); return 0; } pfont->procs.enumerate_glyph = gs_font_cid0_enumerate_glyph; pfont->procs.glyph_outline = z9_glyph_outline; pfont->procs.glyph_info = z9_glyph_info; pfcid = (gs_font_cid0 *)pfont; pfcid->cidata.common = common; pfcid->cidata.CIDMapOffset = CIDMapOffset; pfcid->cidata.FDArray = FDArray; pfcid->cidata.FDArray_size = FDArray_size; pfcid->cidata.FDBytes = FDBytes; pfcid->cidata.glyph_data = z9_glyph_data; pfcid->cidata.proc_data = 0; /* for GC */ if (pfcid->font_name.size == 0) { get_font_name(imemory, &cfnstr, &CIDFontName); copy_font_name(&pfcid->font_name, &cfnstr); } ref_assign(&pfont_data(pfont)->u.cid0.GlyphDirectory, &GlyphDirectory); ref_assign(&pfont_data(pfont)->u.cid0.GlyphData, &GlyphData); ref_assign(&pfont_data(pfont)->u.cid0.DataSource, &DataSource); code = define_gs_font(i_ctx_p, (gs_font *)pfont); if (code >= 0) code = gs_notify_register(&pfont->notify_list, notify_remove_font_type9, pfont); if (code >= 0) { for (i = 0; i < FDArray_size; ++i) { FDArray[i]->dir = pfont->dir; FDArray[i]->data.parent = pfont; } return code; } fail: ifree_object(FDArray, "buildfont9(FDarray)"); return code; }
/* Get one element of a FDArray. */ static int fd_array_element(i_ctx_t *i_ctx_p, gs_font_type1 **ppfont, ref *prfd) { charstring_font_refs_t refs; gs_type1_data data1; build_proc_refs build; gs_font_base *pbfont; gs_font_type1 *pfont; /* * Standard CIDFontType 0 fonts have Type 1 fonts in the FDArray, but * CFF CIDFontType 0 fonts have Type 2 fonts there. */ int fonttype = 1; /* default */ int code = charstring_font_get_refs(prfd, &refs); if (code < 0 || (code = dict_int_param(prfd, "FontType", 1, 2, 1, &fonttype)) < 0 ) return code; /* * We don't handle the alternate Subr representation (SubrCount, * SDBytes, SubrMapOffset) here: currently that is handled in * PostScript code (lib/gs_cidfn.ps). */ switch (fonttype) { case 1: data1.interpret = gs_type1_interpret; data1.subroutineNumberBias = 0; data1.lenIV = DEFAULT_LENIV_1; code = charstring_font_params(imemory, prfd, &refs, &data1); if (code < 0) return code; code = build_proc_name_refs(imemory, &build, "%Type1BuildChar", "%Type1BuildGlyph"); break; case 2: code = type2_font_params(prfd, &refs, &data1); if (code < 0) return code; code = charstring_font_params(imemory, prfd, &refs, &data1); if (code < 0) return code; code = build_proc_name_refs(imemory, &build, "%Type2BuildChar", "%Type2BuildGlyph"); break; default: /* can't happen */ return_error(e_Fatal); } if (code < 0) return code; code = build_gs_FDArray_font(i_ctx_p, prfd, &pbfont, fonttype, &st_gs_font_type1, &build); if (code < 0) return code; pfont = (gs_font_type1 *)pbfont; pbfont->FAPI = NULL; pbfont->FAPI_font_data = NULL; charstring_font_init(pfont, &refs, &data1); pfont->data.procs.glyph_data = z9_FDArray_glyph_data; pfont->data.procs.seac_data = z9_FDArray_seac_data; *ppfont = pfont; return 0; }
/* Common setup for encoding and decoding filters */ static int bhc_setup(os_ptr op, stream_BHC_state * pbhcs) { int code; int num_counts; int data[max_hc_length + 1 + 256 + max_zero_run + 1]; uint dsize; int i; uint num_values, accum; ushort *counts; ushort *values; check_type(*op, t_dictionary); check_dict_read(*op); if ((code = dict_bool_param(op, "FirstBitLowOrder", false, &pbhcs->FirstBitLowOrder)) < 0 || (code = dict_int_param(op, "MaxCodeLength", 1, max_hc_length, max_hc_length, &num_counts)) < 0 || (code = dict_bool_param(op, "EndOfData", true, &pbhcs->EndOfData)) < 0 || (code = dict_uint_param(op, "EncodeZeroRuns", 2, 256, 256, &pbhcs->EncodeZeroRuns)) < 0 || /* Note: the code returned from the following call */ /* is actually the number of elements in the array. */ (code = dict_int_array_param(imemory, op, "Tables", countof(data), data)) <= 0 ) return (code < 0 ? code : gs_note_error(e_rangecheck)); dsize = code; if (dsize <= num_counts + 2) return_error(e_rangecheck); for (i = 0, num_values = 0, accum = 0; i <= num_counts; i++, accum <<= 1 ) { int count = data[i]; if (count < 0) return_error(e_rangecheck); num_values += count; accum += count; } if (dsize != num_counts + 1 + num_values || accum != 1 << (num_counts + 1) || pbhcs->EncodeZeroRuns > (pbhcs->EndOfData ? num_values - 1 : num_values) ) return_error(e_rangecheck); for (; i < num_counts + 1 + num_values; i++) { int value = data[i]; if (value < 0 || value >= num_values) return_error(e_rangecheck); } pbhcs->definition.counts = counts = (ushort *) ialloc_byte_array(num_counts + 1, sizeof(ushort), "bhc_setup(counts)"); pbhcs->definition.values = values = (ushort *) ialloc_byte_array(num_values, sizeof(ushort), "bhc_setup(values)"); if (counts == 0 || values == 0) { ifree_object(values, "bhc_setup(values)"); ifree_object(counts, "bhc_setup(counts)"); return_error(e_VMerror); } for (i = 0; i <= num_counts; i++) counts[i] = data[i]; pbhcs->definition.counts = counts; pbhcs->definition.num_counts = num_counts; for (i = 0; i < num_values; i++) values[i] = data[i + num_counts + 1]; pbhcs->definition.values = values; pbhcs->definition.num_values = num_values; return 0; }
/* or a negative error code. */ int build_gs_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font ** ppfont, font_type ftype, gs_memory_type_ptr_t pstype, const build_proc_refs * pbuild, build_font_options_t options) { ref kname; /* t_string */ ref *pftype; ref *pencoding = 0; bool bitmapwidths; int exactsize, inbetweensize, transformedchar; int wmode; int code; gs_font *pfont; ref *pfid; ref *aop = dict_access_ref(op); bool cpsi_mode = gs_currentcpsimode(imemory); get_font_name(imemory, &kname, op - 1); if (dict_find_string(op, "FontType", &pftype) <= 0 || !r_has_type(pftype, t_integer) || pftype->value.intval != (int)ftype ) return_error(e_invalidfont); if (dict_find_string(op, "Encoding", &pencoding) <= 0) { if (!(options & bf_Encoding_optional)) return_error(e_invalidfont); pencoding = 0; } else { if (!r_is_array(pencoding)) return_error(e_invalidfont); } if (pencoding) { /* observed Adobe behavior */ int count = r_size(pencoding); int type = ftype ? t_name : t_integer; bool fixit = false; while (count--) { ref r; if ((code = array_get(imemory, pencoding, count, &r)) < 0 || !(r_has_type(&r, type) || r_has_type(&r, t_null))) { if (!cpsi_mode && ftype == ft_user_defined) { if (code < 0 || r_has_type(&r, t_null)) { return_error(e_typecheck); } fixit = true; break; } else { return_error(e_typecheck); } } } /* For at least Type 3 fonts, Adobe Distiller will "fix" an Encoding array, as in, for example * Bug 692681 where the arrays contain integers rather than names. Once the font is instantiated * the integers have been converted to names. * It is preferable to to this manipulation here, rather than in Postscript, because we are less * restricted by read-only attributes and VM save levels. */ if (fixit) { ref penc; uint size = 0; char buf[32], *bptr; avm_space curglob = ialloc_space(idmemory); avm_space useglob = r_is_local(pencoding) ? avm_local : avm_global; ialloc_set_space(idmemory, useglob); count = r_size(pencoding); if ((code = ialloc_ref_array(&penc, (r_type_attrs(pencoding) & a_readonly), count, "build_gs_font")) < 0) return code; while (count--) { ref r; if (array_get(imemory, pencoding, count, &r) < 0){ return_error(e_typecheck); } /* For type 3, we know the Encoding entries must be names */ if (r_has_type(&r, t_name)){ ref_assign(&(penc.value.refs[count]), &r); } else { if ((code = obj_cvs(imemory, &r, (byte *)buf, 32, &size, (const byte **)(&bptr))) < 0) { return(code); } if ((code = name_ref(imemory, (const byte *)bptr, size, &r, true)) < 0) return code; ref_assign(&(penc.value.refs[count]), &r); } } if ((code = dict_put_string(osp, "Encoding", &penc, NULL)) < 0) return code; ialloc_set_space(idmemory, curglob); } } if ((code = dict_int_param(op, "WMode", 0, 1, 0, &wmode)) < 0 || (code = dict_bool_param(op, "BitmapWidths", false, &bitmapwidths)) < 0 || (code = dict_int_param(op, "ExactSize", 0, 2, fbit_use_bitmaps, &exactsize)) < 0 || (code = dict_int_param(op, "InBetweenSize", 0, 2, fbit_use_outlines, &inbetweensize)) < 0 || (code = dict_int_param(op, "TransformedChar", 0, 2, fbit_use_outlines, &transformedchar)) < 0 ) return code; code = dict_find_string(op, "FID", &pfid); if (code > 0 && r_has_type(pfid, t_fontID)) { /* silently ignore invalid FID per CET 13-05.ps */ /* * If this font has a FID entry already, it might be a scaled font * made by makefont or scalefont; in a Level 2 environment, it might * be an existing font being registered under a second name, or a * re-encoded font (which was invalid in Level 1, but dvips did it * anyway). */ pfont = r_ptr(pfid, gs_font); /* * If the following condition is false this is a re-encoded font, * or some other questionable situation in which the FID * was preserved. Pretend the FID wasn't there. */ if (obj_eq(pfont->memory, pfont_dict(pfont), op)) { if (pfont->base == pfont) { /* original font */ if (!level2_enabled) return_error(e_invalidfont); *ppfont = pfont; return 1; } else { /* This was made by makefont or scalefont. */ /* Just insert the new name. */ gs_matrix mat; ref fname; /* t_string */ code = sub_font_params(imemory, op, &mat, NULL, &fname); if (code < 0) return code; code = 1; copy_font_name(&pfont->font_name, &fname); goto set_name; } } } /* This is a new font. */ if (!r_has_attr(aop, a_write)) return_error(e_invalidaccess); { ref encoding; /* * Since add_FID may resize the dictionary and cause * pencoding to become invalid, save the Encoding. */ if (pencoding) { encoding = *pencoding; pencoding = &encoding; } code = build_gs_sub_font(i_ctx_p, op, &pfont, ftype, pstype, pbuild, pencoding, op); if (code < 0) return code; } pfont->BitmapWidths = bitmapwidths; pfont->ExactSize = (fbit_type)exactsize; pfont->InBetweenSize = (fbit_type)inbetweensize; pfont->TransformedChar = (fbit_type)transformedchar; pfont->WMode = wmode; pfont->procs.font_info = zfont_info; code = 0; set_name: copy_font_name(&pfont->key_name, &kname); *ppfont = pfont; return code; }
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; }
/* * Fill in the data for a function type 0 parameter object to be used while * we collect the data for the data cube. At the end of the process, we * will create a function type 0 object to be used to calculate values * as a replacement for the original function. */ static int cube_build_func0(const ref * pdict, gs_function_Sd_params_t * params, gs_memory_t *mem) { byte * bytes = 0; int code, i; int total_size; if ((code = dict_int_param(pdict, "Order", 1, 3, 1, ¶ms->Order)) < 0 || (code = dict_int_param(pdict, "BitsPerSample", 1, 32, 0, ¶ms->BitsPerSample)) < 0 || ((code = params->m = fn_build_float_array(pdict, "Domain", false, true, ¶ms->Domain, mem)) < 0 ) || ((code = params->n = fn_build_float_array(pdict, "Range", false, true, ¶ms->Range, mem)) < 0) ) { goto fail; } /* * The previous logic set the size of m and n to the size of the Domain * and Range arrays. This is twice the actual size. Correct this and * check for valid values. */ params->m >>= 1; params->n >>= 1; if (params->m == 0 || params->n == 0 || params->m > MAX_NUM_INPUTS || params->n > MAX_NUM_OUTPUTS) { code = gs_note_error(e_rangecheck); goto fail; } /* * 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. */ { int *ptr = (int *) gs_alloc_byte_array(mem, params->m, sizeof(int), "Size"); if (ptr == NULL) { code = gs_note_error(e_VMerror); goto fail; } params->Size = ptr; code = dict_ints_param(mem, pdict, "Size", params->m, ptr); if (code < 0) goto fail; if (code == 0) { /* * The Size array has not been specified. 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; } else { /* Size array specified - verify valid */ if (code != params->m || !valid_cube_size(params->m, params->n, params->BitsPerSample, params->Size)) code = gs_note_error(e_rangecheck); 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(mem, 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); return 0; fail: gs_function_Sd_free_params(params, mem); return (code < 0 ? code : gs_note_error(e_rangecheck)); }
/* <source> <dict> eexecDecode/filter <file> */ static int zexD(i_ctx_t *i_ctx_p) { os_ptr op = osp; stream_exD_state state; int code; (*s_exD_template.set_defaults)((stream_state *)&state); if (r_has_type(op, t_dictionary)) { uint cstate; bool is_eexec; check_dict_read(*op); if ((code = dict_uint_param(op, "seed", 0, 0xffff, 0x10000, &cstate)) < 0 || (code = dict_int_param(op, "lenIV", 0, max_int, 4, &state.lenIV)) < 0 || (code = dict_bool_param(op, "eexec", false, &is_eexec)) < 0 || (code = dict_bool_param(op, "keep_spaces", false, &state.keep_spaces)) < 0 ) return code; state.cstate = cstate; state.binary = (is_eexec ? -1 : 1); code = 1; } else { state.binary = 1; code = eexec_param(op, &state.cstate); } if (code < 0) return code; /* * If we're reading a .PFB file, let the filter know about it, * so it can read recklessly to the end of the binary section. */ if (r_has_type(op - 1, t_file)) { stream *s = (op - 1)->value.pfile; if (s->state != 0 && s->state->templat == &s_PFBD_template) { stream_PFBD_state *pss = (stream_PFBD_state *)s->state; state.pfb_state = pss; /* * If we're reading the binary section of a PFB stream, * avoid the conversion from binary to hex and back again. */ if (pss->record_type == 2) { /* * The PFB decoder may have converted some data to hex * already. Convert it back if necessary. */ if (pss->binary_to_hex && sbufavailable(s) > 0) { state.binary = 0; /* start as hex */ state.hex_left = sbufavailable(s); } else { state.binary = 1; } pss->binary_to_hex = 0; } } } return filter_read(i_ctx_p, code, &s_exD_template, (stream_state *)&state, 0); }
static int zsethalftone5(i_ctx_t *i_ctx_p) { os_ptr op = osp; uint count; gs_halftone_component *phtc; gs_halftone_component *pc; int code = 0; int j; gs_halftone *pht; gx_device_halftone *pdht; ref sprocs[GS_CLIENT_COLOR_MAX_COMPONENTS + 1]; ref tprocs[GS_CLIENT_COLOR_MAX_COMPONENTS + 1]; gs_memory_t *mem; uint edepth = ref_stack_count(&e_stack); int npop = 2; int dict_enum = dict_first(op); ref rvalue[2]; int cname, colorant_number; byte * pname; uint name_size; int halftonetype, type = 0; gs_state *pgs = igs; int space_index = r_space_index(op - 1); mem = (gs_memory_t *) idmemory->spaces_indexed[space_index]; check_type(*op, t_dictionary); check_dict_read(*op); check_type(op[-1], t_dictionary); check_dict_read(op[-1]); /* * We think that Type 2 and Type 4 halftones, like * screens set by setcolorscreen, adapt automatically to * the device color space, so we need to mark them * with a different internal halftone type. */ dict_int_param(op - 1, "HalftoneType", 1, 5, 0, &type); halftonetype = (type == 2 || type == 4) ? ht_type_multiple_colorscreen : ht_type_multiple; /* Count how many components that we will actually use. */ for (count = 0; ;) { bool have_default = false; /* Move to next element in the dictionary */ if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1) break; /* * Verify that we have a valid component. We may have a * /HalfToneType entry. */ if (!r_has_type(&rvalue[1], t_dictionary)) continue; /* Get the name of the component verify that we will use it. */ cname = name_index(mem, &rvalue[0]); code = gs_get_colorname_string(mem, cname, &pname, &name_size); if (code < 0) break; colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size, halftonetype); if (colorant_number < 0) continue; else if (colorant_number == GX_DEVICE_COLOR_MAX_COMPONENTS) { /* If here then we have the "Default" component */ if (have_default) return_error(e_rangecheck); have_default = true; } count++; /* * Check to see if we have already reached the legal number of * components. */ if (count > GS_CLIENT_COLOR_MAX_COMPONENTS + 1) { code = gs_note_error(e_rangecheck); break; } } check_estack(5); /* for sampling Type 1 screens */ refset_null(sprocs, count); refset_null(tprocs, count); rc_alloc_struct_0(pht, gs_halftone, &st_halftone, imemory, pht = 0, ".sethalftone5"); phtc = gs_alloc_struct_array(mem, count, gs_halftone_component, &st_ht_component_element, ".sethalftone5"); rc_alloc_struct_0(pdht, gx_device_halftone, &st_device_halftone, imemory, pdht = 0, ".sethalftone5"); if (pht == 0 || phtc == 0 || pdht == 0) { j = 0; /* Quiet the compiler: gs_note_error isn't necessarily identity, so j could be left ununitialized. */ code = gs_note_error(e_VMerror); } else { dict_enum = dict_first(op); for (j = 0, pc = phtc; ;) { int type; /* Move to next element in the dictionary */ if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1) break; /* * Verify that we have a valid component. We may have a * /HalfToneType entry. */ if (!r_has_type(&rvalue[1], t_dictionary)) continue; /* Get the name of the component */ cname = name_index(mem, &rvalue[0]); code = gs_get_colorname_string(mem, cname, &pname, &name_size); if (code < 0) break; colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size, halftonetype); if (colorant_number < 0) continue; /* Do not use this component */ pc->cname = cname; pc->comp_number = colorant_number; /* Now process the component dictionary */ check_dict_read(rvalue[1]); if (dict_int_param(&rvalue[1], "HalftoneType", 1, 7, 0, &type) < 0) { code = gs_note_error(e_typecheck); break; } switch (type) { default: code = gs_note_error(e_rangecheck); break; case 1: code = dict_spot_params(&rvalue[1], &pc->params.spot, sprocs + j, tprocs + j); pc->params.spot.screen.spot_function = spot1_dummy; pc->type = ht_type_spot; break; case 3: code = dict_threshold_params(&rvalue[1], &pc->params.threshold, tprocs + j); pc->type = ht_type_threshold; break; case 7: code = dict_threshold2_params(&rvalue[1], &pc->params.threshold2, tprocs + j, imemory); pc->type = ht_type_threshold2; break; } if (code < 0) break; pc++; j++; } } if (code >= 0) { pht->type = halftonetype; pht->params.multiple.components = phtc; pht->params.multiple.num_comp = j; pht->params.multiple.get_colorname_string = gs_get_colorname_string; code = gs_sethalftone_prepare(igs, pht, pdht); } if (code >= 0) { /* * Put the actual frequency and angle in the spot function component dictionaries. */ dict_enum = dict_first(op); for (pc = phtc; ; ) { /* Move to next element in the dictionary */ if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1) break; /* Verify that we have a valid component */ if (!r_has_type(&rvalue[1], t_dictionary)) continue; /* Get the name of the component and verify that we will use it. */ cname = name_index(mem, &rvalue[0]); code = gs_get_colorname_string(mem, cname, &pname, &name_size); if (code < 0) break; colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size, halftonetype); if (colorant_number < 0) continue; if (pc->type == ht_type_spot) { code = dict_spot_results(i_ctx_p, &rvalue[1], &pc->params.spot); if (code < 0) break; } pc++; } } if (code >= 0) { /* * Schedule the sampling of any Type 1 screens, * and any (Type 1 or Type 3) TransferFunctions. * Save the stack depths in case we have to back out. */ uint odepth = ref_stack_count(&o_stack); ref odict, odict5; odict = op[-1]; odict5 = *op; pop(2); op = osp; esp += 5; make_mark_estack(esp - 4, es_other, sethalftone_cleanup); esp[-3] = odict; make_istruct(esp - 2, 0, pht); make_istruct(esp - 1, 0, pdht); make_op_estack(esp, sethalftone_finish); for (j = 0; j < count; j++) { gx_ht_order *porder = NULL; if (pdht->components == 0) porder = &pdht->order; else { /* Find the component in pdht that matches component j in the pht; gs_sethalftone_prepare() may permute these. */ int k; int comp_number = phtc[j].comp_number; for (k = 0; k < count; k++) { if (pdht->components[k].comp_number == comp_number) { porder = &pdht->components[k].corder; break; } } } switch (phtc[j].type) { case ht_type_spot: code = zscreen_enum_init(i_ctx_p, porder, &phtc[j].params.spot.screen, &sprocs[j], 0, 0, space_index); if (code < 0) break; /* falls through */ case ht_type_threshold: if (!r_has_type(tprocs + j, t__invalid)) { /* Schedule TransferFunction sampling. */ /****** check_xstack IS WRONG ******/ check_ostack(zcolor_remap_one_ostack); check_estack(zcolor_remap_one_estack); code = zcolor_remap_one(i_ctx_p, tprocs + j, porder->transfer, igs, zcolor_remap_one_finish); op = osp; } break; default: /* not possible here, but to keep */ /* the compilers happy.... */ ; } if (code < 0) { /* Restore the stack. */ ref_stack_pop_to(&o_stack, odepth); ref_stack_pop_to(&e_stack, edepth); op = osp; op[-1] = odict; *op = odict5; break; } npop = 0; } } if (code < 0) { gs_free_object(mem, pdht, ".sethalftone5"); gs_free_object(mem, phtc, ".sethalftone5"); gs_free_object(mem, pht, ".sethalftone5"); return code; } pop(npop); return (ref_stack_count(&e_stack) > edepth ? o_push_estack : 0); }
/* Collect parameters for a mesh shading. */ static int build_mesh_shading(i_ctx_t *i_ctx_p, const ref * op, gs_shading_mesh_params_t * params, float **pDecode, gs_function_t ** pFunction, gs_memory_t *mem) { int code; float *data = 0; ref *pDataSource; *pDecode = 0; *pFunction = 0; if (dict_find_string(op, "DataSource", &pDataSource) <= 0) return_error(gs_error_rangecheck); if (r_is_array(pDataSource)) { uint size = r_size(pDataSource); data = (float *)gs_alloc_byte_array(mem, size, sizeof(float), "build_mesh_shading"); if (data == 0) return_error(gs_error_VMerror); code = process_float_array(mem, pDataSource, size, data); if (code < 0) { gs_free_object(mem, data, "build_mesh_shading"); return code; } data_source_init_floats(¶ms->DataSource, data, size); } else switch (r_type(pDataSource)) { case t_file: { stream *s; check_read_file(i_ctx_p, s, pDataSource); data_source_init_stream(¶ms->DataSource, s); break; } case t_string: check_read(*pDataSource); data_source_init_string2(¶ms->DataSource, pDataSource->value.bytes, r_size(pDataSource)); break; default: return_error(gs_error_typecheck); } code = build_shading_function(i_ctx_p, op, pFunction, 1, mem, NULL); if (code < 0) { gs_free_object(mem, data, "build_mesh_shading"); return code; } if (data_source_is_array(params->DataSource)) { params->BitsPerCoordinate = 0; params->BitsPerComponent = 0; } else { int num_decode = 4 + (*pFunction != 0 ? 1 : gs_color_space_num_components(params->ColorSpace)) * 2; if ((code = dict_int_param(op, "BitsPerCoordinate", 1, 32, 0, ¶ms->BitsPerCoordinate)) >= 0 && (code = dict_int_param(op, "BitsPerComponent", 1, 16, 0, ¶ms->BitsPerComponent)) >= 0 ) { *pDecode = (float *) gs_alloc_byte_array(mem, num_decode, sizeof(float), "build_mesh_shading"); if (*pDecode == 0) code = gs_note_error(gs_error_VMerror); else { code = dict_floats_param(mem, op, "Decode", num_decode, *pDecode, NULL); if (code < 0) { gs_free_object(mem, *pDecode, "build_mesh_shading"); *pDecode = 0; } } } } if (code < 0) { if (*pFunction != 0) { gs_function_free(*pFunction, true, mem); *pFunction = 0; } gs_free_object(mem, data, "build_mesh_shading"); } return code; }