/* * <dict> .seticcspace - * * Create an ICCBased color space and set it to be the current color space. * * The PostScript structure of an ICCBased color space is that same as that * for a CIEBased* color space: * * [ /ICCBased <dictionary> ] * * As is the for other .setcie*space operators, the operand dictionary rather * than the complete color space array is on the stack when this operator * is inovked. * * At the time this procedure is called, the alternative color space for * the ICCBased color space is expected to be the current color space, * whether that space was explicitly specified or implied by the number * of components in the ICCBased color space dictionary. This is consistent * with the handling of alternative spaces in Separation, DeviceN, and * Indexed color spaces. Unlike the "zset*space" routines for those spaces, * however, the current code does not attempt to build the color space * "in place" in the graphic state. * * The procedure that invokes this operator will already have checked that * the operand is a dictionary, is readable, and defines the key /N * (number of components). */ static int zseticcspace(i_ctx_t * i_ctx_p) { os_ptr op = osp; int code; gs_color_space * palt_cs; ref * pnval; ref * pstrmval; stream * s; int i, ncomps; float range_buff[8]; static const float dflt_range[8] = { 0, 1, 0, 1, 0, 1, 0, 1 }; code = dict_find_string(op, "N", &pnval); if (code < 0) return code; ncomps = pnval->value.intval; if (2*ncomps > sizeof(range_buff)/sizeof(range_buff[0])) return_error(e_rangecheck); /* verify the DataSource entry */ if (dict_find_string(op, "DataSource", &pstrmval) <= 0) return_error(e_undefined); check_read_file(i_ctx_p, s, pstrmval); /* * Verify that the current color space can be a alternative color space. * The check for ICCBased color space is a hack to avoid introducing yet * another category indicator into the gs_color_space_type structur. */ palt_cs = gs_currentcolorspace(igs); if ( !palt_cs->type->can_be_alt_space || gs_color_space_get_index(palt_cs) == gs_color_space_index_ICC ) return_error(e_rangecheck); /* * Fetch and verify the Range array. * * The PDF documentation is unclear as to the purpose of this array. * Essentially all that is stated is that "These values must match the * information in the ICC profile" (PDF Reference, 2nd ed., p. 174). * If that is the case, why not use the information in the profile? * The only reason we can think of is range specification is intended * to be used to limit the range of values passed to the alternate * color space (the range may be smaller than the native range of values * provided by that color space). * * Because the cms code will perform normalization based on color * space, we use the range values only to restrict the set of input * values; they are not used for normalization. */ code = dict_floats_param( imemory, op, "Range", 2 * ncomps, range_buff, dflt_range ); for (i = 0; i < 2 * ncomps && range_buff[i + 1] >= range_buff[i]; i += 2) ; if (i != 2 * ncomps) return_error(e_rangecheck); return seticc(i_ctx_p, ncomps, op, range_buff); }
/* Check that a UID in a dictionary is equal to an existing, valid UID. */ bool dict_check_uid_param(const ref * pdict, const gs_uid * puid) { ref *puniqueid; if (uid_is_XUID(puid)) { uint size = uid_XUID_size(puid); uint i; if (dict_find_string(pdict, "XUID", &puniqueid) <= 0) return false; if (!r_has_type(puniqueid, t_array) || r_size(puniqueid) != size ) return false; for (i = 0; i < size; i++) { const ref *pvalue = puniqueid->value.const_refs + i; if (!r_has_type(pvalue, t_integer)) return false; if (pvalue->value.intval != uid_XUID_values(puid)[i]) return false; } return true; } else { if (dict_find_string(pdict, "UniqueID", &puniqueid) <= 0) return false; return (r_has_type(puniqueid, t_integer) && puniqueid->value.intval == puid->id); } }
static int font_with_same_UID_and_another_metrics(const gs_font *pfont0, const gs_font *pfont1) { const gs_font_base *pbfont0 = (const gs_font_base *)pfont0; const gs_font_base *pbfont1 = (const gs_font_base *)pfont1; if (uid_equal(&pbfont0->UID, &pbfont1->UID)) { const ref *pfdict0 = &pfont_data(gs_font_parent(pbfont0))->dict; const ref *pfdict1 = &pfont_data(gs_font_parent(pbfont1))->dict; ref *pmdict0, *pmdict1; if (pbfont0->WMode || dict_find_string(pfdict0, "Metrics", &pmdict0) <= 0) pmdict0 = NULL; if (pbfont1->WMode || dict_find_string(pfdict1, "Metrics", &pmdict1) <= 0) pmdict1 = NULL; if (!pmdict0 != !pmdict1) return 1; if (pmdict0 != NULL && !obj_eq(pfont0->memory, pmdict0, pmdict1)) return 1; if (!pbfont0->WMode || dict_find_string(pfdict0, "Metrics2", &pmdict0) <= 0) pmdict0 = NULL; if (!pbfont0->WMode || dict_find_string(pfdict1, "Metrics2", &pmdict1) <= 0) pmdict1 = NULL; if (!pmdict0 != !pmdict1) return 1; if (pmdict0 != NULL && !obj_eq(pfont0->memory, pmdict0, pmdict1)) return 1; } return 0; }
/* Get the BuildChar and/or BuildGlyph routines from a (base) font. */ int build_gs_font_procs(os_ptr op, build_proc_refs * pbuild) { int ccode, gcode; ref *pBuildChar; ref *pBuildGlyph; check_type(*op, t_dictionary); ccode = dict_find_string(op, "BuildChar", &pBuildChar); gcode = dict_find_string(op, "BuildGlyph", &pBuildGlyph); if (ccode <= 0) { if (gcode <= 0) return_error(e_invalidfont); make_null(&pbuild->BuildChar); } else { check_proc(*pBuildChar); pbuild->BuildChar = *pBuildChar; } if (gcode <= 0) make_null(&pbuild->BuildGlyph); else { check_proc(*pBuildGlyph); pbuild->BuildGlyph = *pBuildGlyph; } return 0; }
/* The caller guarantees that *op is a dictionary. */ int build_gs_primitive_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) { ref *pcharstrings = 0; ref CharStrings; gs_font_base *pfont; font_data *pdata; int code; if (dict_find_string(op, "CharStrings", &pcharstrings) <= 0) { if (!(options & bf_CharStrings_optional)) return_error(e_invalidfont); } else { ref *ignore; if (!r_has_type(pcharstrings, t_dictionary)) return_error(e_invalidfont); if ((options & bf_notdef_required) != 0 && dict_find_string(pcharstrings, ".notdef", &ignore) <= 0 ) return_error(e_invalidfont); /* * Since build_gs_simple_font may resize the dictionary and cause * pointers to become invalid, save CharStrings. */ CharStrings = *pcharstrings; } code = build_gs_outline_font(i_ctx_p, op, ppfont, ftype, pstype, pbuild, options, build_gs_simple_font); if (code != 0) return code; pfont = *ppfont; pdata = pfont_data(pfont); if (pcharstrings) ref_assign(&pdata->CharStrings, &CharStrings); else make_null(&pdata->CharStrings); /* Check that the UniqueIDs match. This is part of the */ /* Adobe protection scheme, but we may as well emulate it. */ if (uid_is_valid(&pfont->UID) && !dict_check_uid_param(op, &pfont->UID) ) uid_set_invalid(&pfont->UID); if (uid_is_valid(&pfont->UID)) { const gs_font *pfont0 = (const gs_font *)pfont; code = gs_font_find_similar(ifont_dir, &pfont0, font_with_same_UID_and_another_metrics); if (code < 0) return code; /* Must not happen. */ if (code) uid_set_invalid(&pfont->UID); } return 0; }
/* <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); }
/* * Files created with .tempfile permit some operations even if the * temp directory is not explicitly named on the PermitFile... path * The names 'SAFETY' and 'tempfiles' are defined by gs_init.ps */ static bool file_is_tempfile(i_ctx_t *i_ctx_p, const uchar *fname, int len) { ref *SAFETY; ref *tempfiles; ref kname; if (dict_find_string(systemdict, "SAFETY", &SAFETY) <= 0 || dict_find_string(SAFETY, "tempfiles", &tempfiles) <= 0) return false; if (name_ref(imemory, fname, len, &kname, -1) < 0 || dict_find(tempfiles, &kname, &SAFETY) <= 0) return false; return true; }
/* Validate a font parameter. */ int font_param(const ref * pfdict, gs_font ** ppfont) { /* * Check that pfdict is a read-only dictionary, that it has a FID * entry whose value is a fontID, and that the fontID points to a * gs_font structure whose associated PostScript dictionary is * pfdict. */ ref *pid; gs_font *pfont; const font_data *pdata; check_type(*pfdict, t_dictionary); if (dict_find_string(pfdict, "FID", &pid) <= 0 || !r_has_type(pid, t_fontID) ) return_error(e_invalidfont); pfont = r_ptr(pid, gs_font); if (pfont == 0) return_error(e_invalidfont); /* unregistered font */ pdata = pfont->client_data; if (!obj_eq(pfont->memory, &pdata->dict, pfdict)) return_error(e_invalidfont); *ppfont = pfont; return 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)); }
/* and return maxlen. */ int dict_float_array_check_param(const gs_memory_t *mem, const ref * pdict, const char *kstr, uint len, float *fvec, const float *defaultvec, int under_error, int over_error) { ref *pdval; uint size; int code; if (pdict == 0 || dict_find_string(pdict, kstr, &pdval) <= 0) { if (defaultvec == NULL) return 0; memcpy(fvec, defaultvec, len * sizeof(float)); return len; } if (!r_is_array(pdval)) return_error(e_typecheck); size = r_size(pdval); if (size > len) return_error(over_error); code = process_float_array(mem, pdval, size, fvec); return (code < 0 ? code : size == len || under_error >= 0 ? size : gs_note_error(under_error)); }
/* a missing value will return e_undefined rather than 1. */ int dict_uint_param(const ref * pdict, const char *kstr, uint minval, uint maxval, uint defaultval, uint * pvalue) { ref *pdval; int code; uint ival; if (pdict == 0 || dict_find_string(pdict, kstr, &pdval) <= 0) { ival = defaultval; code = 1; } else { check_type_only(*pdval, t_integer); if (pdval->value.intval != (uint) pdval->value.intval) return_error(e_rangecheck); ival = (uint) pdval->value.intval; code = 0; } if (ival < minval || ival > maxval) { if (code == 1) return_error(e_undefined); else return_error(e_rangecheck); } *pvalue = ival; return code; }
/* 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_aes_d(i_ctx_t * i_ctx_p) { os_ptr op = osp; /* i_ctx_p->op_stack.stack.p defined in osstack.h */ ref *sop = NULL; stream_aes_state state; int use_padding; /* extract the key from the parameter dictionary */ check_type(*op, t_dictionary); check_dict_read(*op); if (dict_find_string(op, "Key", &sop) <= 0) return_error(gs_error_rangecheck); s_aes_set_key(&state, sop->value.const_bytes, r_size(sop)); /* extract the padding flag, which defaults to true for compatibility */ if (dict_bool_param(op, "Padding", 1, &use_padding) < 0) return_error(gs_error_rangecheck); s_aes_set_padding(&state, use_padding); /* we pass npop=0, since we've no arguments left to consume */ /* FIXME: passing 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 caused no trouble when we were the arcfour cipher and maintained no pointers. */ return filter_read(i_ctx_p, 0, &s_aes_template, (stream_state *) & state, 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; }
/* <source> <dict> /JBIG2Decode <file> */ static int z_jbig2decode(i_ctx_t * i_ctx_p) { os_ptr op = osp; ref *sop = NULL; s_jbig2_global_data_t *gref; stream_jbig2decode_state state; /* Extract the global context reference, if any, from the parameter dictionary and embed it in our stream state. The original object ref is under the JBIG2Globals key. We expect the postscript code to resolve this and call z_jbig2makeglobalctx() below to create an astruct wrapping the global decoder data and store it under the .jbig2globalctx key */ s_jbig2decode_set_global_data((stream_state*)&state, NULL); if (r_has_type(op, t_dictionary)) { check_dict_read(*op); if ( dict_find_string(op, ".jbig2globalctx", &sop) > 0) { gref = r_ptr(sop, s_jbig2_global_data_t); s_jbig2decode_set_global_data((stream_state*)&state, gref); } } /* we pass npop=0, since we've no arguments left to consume */ return filter_read(i_ctx_p, 0, &s_jbig2decode_template, (stream_state *) & state, (sop ? r_space(sop) : 0)); }
/* * Get CDevProc. */ bool zchar_get_CDevProc(const gs_font_base * pbfont, ref **ppcdevproc) { const ref *pfdict = &pfont_data(gs_font_parent(pbfont))->dict; return dict_find_string(pfdict, "CDevProc", ppcdevproc) > 0; }
/* (This is a single-use procedure, for clearer code.) */ static bool fid_eq(const gs_memory_t *mem, const gs_font *pfont1, const gs_font *pfont2) { while (pfont1->base != pfont1) pfont1 = pfont1->base; while (pfont2->base != pfont2) pfont2 = pfont2->base; if (pfont1 == pfont2) return true; switch (pfont1->FontType) { case 1: case 3: if (pfont1->FontType == pfont2->FontType) break; default: return false; } /* The following, while peculiar, appears to match CPSI. */ { const gs_uid *puid1 = &((const gs_font_base *)pfont1)->UID; const gs_uid *puid2 = &((const gs_font_base *)pfont2)->UID; if (uid_is_UniqueID(puid1) || uid_is_UniqueID(puid2) || ((uid_is_XUID(puid1) || uid_is_XUID(puid2)) && !uid_equal(puid1, puid2))) return false; } { const font_data *pfd1 = (const font_data *)pfont1->client_data; const font_data *pfd2 = (const font_data *)pfont2->client_data; if (!(obj_eq(mem, &pfd1->BuildChar, &pfd2->BuildChar) && obj_eq(mem, &pfd1->BuildGlyph, &pfd2->BuildGlyph) && obj_eq(mem, &pfd1->Encoding, &pfd2->Encoding) && obj_eq(mem, &pfd1->CharStrings, &pfd2->CharStrings))) return false; if (pfont1->FontType == 1) { ref *ppd1, *ppd2; if (dict_find_string(&pfd1->dict, "Private", &ppd1) > 0 && dict_find_string(&pfd2->dict, "Private", &ppd2) > 0 && !obj_eq(mem, ppd1, ppd2)) return false; } } return true; }
void get_GlyphNames2Unicode(i_ctx_t *i_ctx_p, gs_font *pfont, ref *pdref) { ref *pfontinfo = NULL, *g2u = NULL; font_data *pdata; if (dict_find_string(pdref, "FontInfo", &pfontinfo) <= 0 || !r_has_type(pfontinfo, t_dictionary) || dict_find_string(pfontinfo, "GlyphNames2Unicode", &g2u) <= 0 || !r_has_type(pfontinfo, t_dictionary)) return; /* * Since build_gs_font may resize the dictionary and cause * pointers to become invalid, save Glyph2Unicode */ pdata = pfont_data(pfont); ref_assign_new(&pdata->GlyphNames2Unicode, g2u); }
/* Get the CIDSystemInfo of a CIDFont. */ int cid_font_system_info_param(gs_cid_system_info_t *pcidsi, const ref *prfont) { ref *prcidsi; if (dict_find_string(prfont, "CIDSystemInfo", &prcidsi) <= 0) return_error(e_rangecheck); return cid_system_info_param(pcidsi, prcidsi); }
/* Get a matrix from a dictionary. */ int dict_matrix_param(const gs_memory_t *mem, const ref * pdict, const char *kstr, gs_matrix * pmat) { ref *pdval; if (pdict == 0 || dict_find_string(pdict, kstr, &pdval) <= 0) return_error(e_typecheck); return read_matrix(mem, pdval, pmat); }
/* Take a key's value from a given dictionary, create [/key any] array, * and store it in $error.errorinfo. * The key must be a permanently allocated C string. */ void gs_errorinfo_put_pair_from_dict(i_ctx_t *i_ctx_p, const ref *op, const char *key) { ref *val, n; if (dict_find_string(op, key, &val) <= 0) { make_null(&n); val = &n; } gs_errorinfo_put_pair(i_ctx_p, key, strlen(key), val); }
/* Make a transformed font (common code for makefont/scalefont). */ static int make_font(i_ctx_t *i_ctx_p, const gs_matrix * pmat) { os_ptr op = osp; os_ptr fp = op - 1; gs_font *oldfont, *newfont; int code; ref *pencoding = 0; code = font_param(fp, &oldfont); if (code < 0) return code; { uint space = ialloc_space(idmemory); ialloc_set_space(idmemory, r_space(fp)); if (dict_find_string(fp, "Encoding", &pencoding) > 0 && !r_is_array(pencoding) ) code = gs_note_error(e_invalidfont); else { /* * Temporarily substitute the new dictionary * for the old one, in case the Encoding changed. */ ref olddict; olddict = *pfont_dict(oldfont); *pfont_dict(oldfont) = *fp; code = gs_makefont(ifont_dir, oldfont, pmat, &newfont); *pfont_dict(oldfont) = olddict; } ialloc_set_space(idmemory, space); } if (code < 0) return code; /* * We have to allow for the possibility that the font's Encoding * is different from that of the base font. Note that the * font_data of the new font was simply copied from the old one. */ if (pencoding != 0 && !obj_eq(imemory, pencoding, &pfont_data(newfont)->Encoding) ) { if (newfont->FontType == ft_composite) return_error(e_rangecheck); /* We should really do validity checking here.... */ ref_assign(&pfont_data(newfont)->Encoding, pencoding); lookup_gs_simple_font_encoding((gs_font_base *) newfont); } *fp = *pfont_dict(newfont); pop(1); return 0; }
/* * Get the additional parameters for a Type 2 font (or FontType 2 FDArray * entry in a CIDFontType 0 font), beyond those common to Type 1 and Type 2 * fonts. */ int type2_font_params(const_os_ptr op, charstring_font_refs_t *pfr, gs_type1_data *pdata1) { int code; float dwx, nwx; ref *temp; pdata1->interpret = gs_type2_interpret; pdata1->lenIV = DEFAULT_LENIV_2; pdata1->subroutineNumberBias = subr_bias(pfr->Subrs); /* Get information specific to Type 2 fonts. */ if (dict_find_string(pfr->Private, "GlobalSubrs", &temp) > 0) { if (!r_is_array(temp)) return_error(e_typecheck); pfr->GlobalSubrs = temp; } pdata1->gsubrNumberBias = subr_bias(pfr->GlobalSubrs); if ((code = dict_uint_param(pfr->Private, "gsubrNumberBias", 0, max_uint, pdata1->gsubrNumberBias, &pdata1->gsubrNumberBias)) < 0 || (code = dict_float_param(pfr->Private, "defaultWidthX", 0.0, &dwx)) < 0 || (code = dict_float_param(pfr->Private, "nominalWidthX", 0.0, &nwx)) < 0 ) return code; pdata1->defaultWidthX = float2fixed(dwx); pdata1->nominalWidthX = float2fixed(nwx); { ref *pirs; if (dict_find_string(pfr->Private, "initialRandomSeed", &pirs) <= 0) pdata1->initialRandomSeed = 0; else if (!r_has_type(pirs, t_integer)) return_error(e_typecheck); else pdata1->initialRandomSeed = pirs->value.intval; } return 0; }
/* According to PLRM 3rd ed, p. 264 "indexed color space is not * allowed in any shading whose color values are generated by a function; * this applies to any shading dictionary that contains a Function entry." * Adobe interpreters follow PLRM in this respect and we follow them. */ static int check_indexed_vs_function(i_ctx_t *i_ctx_p, const ref *op, const gs_color_space *pcs, const gs_function_t *funct) { if (funct && gs_color_space_get_index(pcs) == gs_color_space_index_Indexed) { static const char fn[] = "Function"; ref *f; if (dict_find_string(op, fn, &f) > 0) gs_errorinfo_put_pair(i_ctx_p, fn, sizeof(fn) - 1, f); return_error(gs_error_typecheck); /* CET 12-14a */ } return 0; }
/* Collect a Function value. */ static int build_shading_function(i_ctx_t *i_ctx_p, const ref * op, gs_function_t ** ppfn, int num_inputs, gs_memory_t *mem, const float *shading_domain) { ref *pFunction; int code; *ppfn = 0; if (dict_find_string(op, "Function", &pFunction) <= 0) return 0; if (r_is_array(pFunction)) { uint size = r_size(pFunction); gs_function_t **Functions; uint i; gs_function_AdOt_params_t params; check_read(*pFunction); if (size == 0) return_error(gs_error_rangecheck); code = alloc_function_array(size, &Functions, mem); if (code < 0) return code; for (i = 0; i < size; ++i) { ref rsubfn; array_get(imemory, pFunction, (long)i, &rsubfn); code = fn_build_function(i_ctx_p, &rsubfn, &Functions[i], mem, shading_domain, num_inputs); if (code < 0) break; } params.m = num_inputs; params.Domain = 0; params.n = size; params.Range = 0; params.Functions = (const gs_function_t * const *)Functions; if (code >= 0) code = gs_function_AdOt_init(ppfn, ¶ms, mem); if (code < 0) gs_function_AdOt_free_params(¶ms, mem); } else { code = fn_build_function(i_ctx_p, pFunction, ppfn, mem, shading_domain, num_inputs); if (code < 0) return code; if ((*ppfn)->params.m != num_inputs) { gs_function_free(*ppfn, true, mem); return_error(gs_error_rangecheck); } } return code; }
static int ref_param_read_get_policy(gs_param_list * plist, gs_param_name pkey) { iparam_list *const iplist = (iparam_list *) plist; ref *pvalue; if (!(r_has_type(&iplist->u.r.policies, t_dictionary) && dict_find_string(&iplist->u.r.policies, pkey, &pvalue) > 0 && r_has_type(pvalue, t_integer)) ) return gs_param_policy_ignore; return (int)pvalue->value.intval; }
/* Do dict_floats_param() and store [/key any] array in $error.errorinfo * on failure. The key must be a permanently allocated C string. */ int dict_floats_param_errorinfo(i_ctx_t *i_ctx_p, const ref * pdict, const char *kstr, uint maxlen, float *fvec, const float *defaultvec) { ref *val; int code = dict_float_array_check_param(imemory, pdict, kstr, maxlen, fvec, defaultvec, e_rangecheck, e_rangecheck); if (code < 0) { if (dict_find_string(pdict, kstr, &val) > 0) gs_errorinfo_put_pair(i_ctx_p, kstr, strlen(kstr), val); } 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); }
/* font_info procedure */ static bool zfont_info_has(const ref *pfidict, const char *key, gs_const_string *pmember) { ref *pvalue; if (dict_find_string(pfidict, key, &pvalue) > 0 && r_has_type(pvalue, t_string) ) { pmember->data = pvalue->value.const_bytes; pmember->size = r_size(pvalue); return true; } return false; }
/* Set actual frequency and angle in a dictionary. */ static int dict_real_result(i_ctx_t *i_ctx_p, ref * pdict, const char *kstr, floatp val) { int code = 0; ref *ignore; if (dict_find_string(pdict, kstr, &ignore) > 0) { ref rval; check_dict_write(*pdict); make_real(&rval, val); code = idict_put_string(pdict, kstr, &rval); } return code; }