/* setcolor */ int gs_setcolor(gs_state * pgs, const gs_client_color * pcc) { gs_color_space * pcs = pgs->color[0].color_space; gs_client_color cc_old = *pgs->color[0].ccolor; gx_device_color *dev_color = pgs->color[0].dev_color; bool do_unset = true; if (pgs->in_cachedevice) return_error(gs_error_undefined); /* PLRM3 page 215. */ if (dev_color->ccolor_valid && gx_dc_is_pure(dev_color)) { /* change of colorspace will set type to _none */ int i; int ncomps = cs_num_components(pcs); for(i=0; i < ncomps; i++) if (dev_color->ccolor.paint.values[i] != pcc->paint.values[i]) break; do_unset = i < ncomps; /* if i == ncomps, color unchanged, optimized */ } if (do_unset) gx_unset_dev_color(pgs); (*pcs->type->adjust_color_count)(pcc, pcs, 1); *pgs->color[0].ccolor = *pcc; (*pcs->type->restrict_color)(pgs->color[0].ccolor, pcs); (*pcs->type->adjust_color_count)(&cc_old, pcs, -1); return 0; }
/* Allocate, and prepare to load, the index or tint map. */ int zcs_begin_map(i_ctx_t *i_ctx_p, gs_indexed_map ** pmap, const ref * pproc, int num_entries, const gs_color_space * base_space, op_proc_t map1) { gs_memory_t *mem = gs_state_memory(igs); int space = imemory_space((gs_ref_memory_t *)mem); int num_components = cs_num_components(base_space); int num_values = num_entries * num_components; gs_indexed_map *map; int code = alloc_indexed_map(&map, num_values, mem, "setcolorspace(mapped)"); es_ptr ep; if (code < 0) return code; *pmap = map; /* Map the entire set of color indices. Since the */ /* o-stack may not be able to hold N*4096 values, we have */ /* to load them into the cache as they are generated. */ check_estack(num_csme + 1); /* 1 extra for map1 proc */ ep = esp += num_csme; make_int(ep + csme_num_components, num_components); make_struct(ep + csme_map, space, map); ep[csme_proc] = *pproc; make_int(ep + csme_hival, num_entries - 1); make_int(ep + csme_index, -1); push_op_estack(map1); return o_push_estack; }
/* * Get the number of components in a Pattern color. * For backward compatibility, and to distinguish Pattern color spaces * from all others, we negate the result. */ static int gx_num_components_Pattern(const gs_color_space * pcs) { return (pcs->params.pattern.has_base_space ? -1 - cs_num_components(pcs->base_space) : -1 /* Pattern dictionary only */ ); }
/* Define a lookup_index procedure that just returns the map values. */ int lookup_indexed_map(const gs_indexed_params * params, int index, float *values) { int m = cs_num_components((const gs_color_space *)¶ms->base_space); const float *pv = ¶ms->lookup.map->values[index * m]; memcpy(values, pv, sizeof(*values) * m); return 0; }
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; }
/* Note that, to support PDF, ICCBased color spaces may be used to substitute * for the Device* color spaces (previously, only CIEBased color spaces could * be used for this purpose). */ int gs_setsubstitutecolorspace(gs_state *pgs, gs_color_space_index csi, const gs_color_space *pcs) { int index = (int)csi; static const uint masks[3] = { (1 << gs_color_space_index_DeviceGray) | (1 << gs_color_space_index_CIEA), (1 << gs_color_space_index_DeviceRGB) | (1 << gs_color_space_index_CIEABC) | (1 << gs_color_space_index_CIEDEF), (1 << gs_color_space_index_DeviceCMYK) | (1 << gs_color_space_index_CIEDEFG) }; const gs_color_space *pcs_old; if (index < 0 || index > 2) return_error(gs_error_rangecheck); if (pcs) { if (gs_color_space_get_index(pcs) == gs_color_space_index_CIEICC) { static const byte dev_ncomps[3] = {1, 3, 4}; if (dev_ncomps[index] != cs_num_components(pcs)) return_error(gs_error_rangecheck); } else if (!masks[index] && (1 << gs_color_space_get_index(pcs))) return_error(gs_error_rangecheck); } pcs_old = pgs->device_color_spaces.indexed[index]; if (pcs_old == 0 && (pcs == 0 || gs_color_space_get_index(pcs) == csi)) return 0; rc_assign(pgs->device_color_space.indexed[index], (pcs ? pcs : pgs->shared->device_color_spaces.indexed[index]), "gs_setsubstitutecolorspace"); return 0; }
int gs_begin_transparency_group(gs_state *pgs, const gs_transparency_group_params_t *ptgp, const gs_rect *pbbox) { gs_pdf14trans_params_t params = { 0 }; const gs_color_space *blend_color_space; gs_imager_state * pis = (gs_imager_state *)pgs; cmm_profile_t *profile; if (check_for_nontrans_pattern(pgs, (unsigned char *)"gs_begin_transparency_group")) { return(0); } /* * Put parameters into a compositor parameter and then call the * create_compositor. This will pass the data to the PDF 1.4 * transparency device. */ params.pdf14_op = PDF14_BEGIN_TRANS_GROUP; params.Isolated = ptgp->Isolated; params.Knockout = ptgp->Knockout; params.image_with_SMask = ptgp->image_with_SMask; params.opacity = pgs->opacity; params.shape = pgs->shape; params.blend_mode = pgs->blend_mode; /* This function is called during the c-list writer side. Store some information so that we know what the color space is so that we can adjust according later during the clist reader. We currently will use the concrete space for any space other than a device space. However, if the device is a sep device it will blend in DeviceN color space as required. */ blend_color_space = gs_currentcolorspace_inline(pgs); if (gs_color_space_get_index(blend_color_space) > gs_color_space_index_DeviceCMYK) { /* ICC and PS CIE based case. Note that unidirectional PS CIE color spaces should not be allowed but end up occuring when processing PDF files with -dUseCIEColor. We will end up using the appropriate ICC default color space in these cases. */ blend_color_space = gs_currentcolorspace_inline(pgs); } else { blend_color_space = cs_concrete_space(blend_color_space, pis); } /* Note that if the /CS parameter was NOT present in the push of the transparency group, then we must actually inherent the previous group color space, or the color space of the target device (process color model). Here we just want to set it as a unknown type for clist writing, as we will take care of using the parent group color space later during clist reading. Also, if the group was not isolated we MUST use the parent group color space regardless of what the group color space is specified to be */ if (ptgp->ColorSpace == NULL || params.Isolated != true) { params.group_color = UNKNOWN; params.group_color_numcomps = 0; } else { /* The /CS parameter was present. Use what was set. Currently all our Device spaces are actually ICC based. The other options are if -dUseCIEColor is set, in which case it could be coming in as a PS CIE color space, which should not be allowed but should default to one of the default ICC color spaces. Note that CalRGB and CalGray, which are valid bidirectional color spaces are converted to ICC profiles during installation. PS CIE building to ICC is delayed. */ if ( gs_color_space_is_ICC(blend_color_space) ) { /* Blending space is ICC based. If we are doing c-list rendering we will need to write this color space into the clist. */ params.group_color = ICC; params.group_color_numcomps = blend_color_space->cmm_icc_profile_data->num_comps; /* Get the ICC profile */ params.iccprofile = blend_color_space->cmm_icc_profile_data; params.icc_hash = blend_color_space->cmm_icc_profile_data->hashcode; } else { /* Color space was NOT ICC based. PS CIE space and DeviceN are the only other option. Use the ICC default based upon the component count. */ switch (cs_num_components(blend_color_space)) { case 1: profile = pgs->icc_manager->default_gray; break; case 3: profile = pgs->icc_manager->default_rgb; break; case 4: profile = pgs->icc_manager->default_cmyk; break; default: /* We can end up here if we are in a deviceN color space and we have a sep output device */ profile = NULL; params.group_color = DEVICEN; params.group_color_numcomps = cs_num_components(blend_color_space); break; } if (profile != NULL) { params.group_color = ICC; params.group_color_numcomps = profile->num_comps; params.iccprofile = profile; params.icc_hash = profile->hashcode; } } } #ifdef DEBUG if (gs_debug_c('v')) { static const char *const cs_names[] = { GS_COLOR_SPACE_TYPE_NAMES }; dmlprintf6(pgs->memory, "[v](0x%lx)begin_transparency_group [%g %g %g %g] Num_grp_clr_comp = %d\n", (ulong)pgs, pbbox->p.x, pbbox->p.y, pbbox->q.x, pbbox->q.y,params.group_color_numcomps); if (ptgp->ColorSpace) dmprintf1(pgs->memory, " CS = %s", cs_names[(int)gs_color_space_get_index(ptgp->ColorSpace)]); else dmputs(pgs->memory, " (no CS)"); dmprintf2(pgs->memory, " Isolated = %d Knockout = %d\n", ptgp->Isolated, ptgp->Knockout); } #endif params.bbox = *pbbox; return gs_state_update_pdf14trans(pgs, ¶ms); }
/* * 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_in, const pdf_color_space_names_t *pcsn, bool by_name, const byte *res_name, int name_length) { const gs_color_space *pcs; gs_color_space_index csi; 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 0 bool islab = false; #endif /* If color space is CIE based and we have compatibility then go ahead and use the ICC alternative */ if ((pdev->CompatibilityLevel < 1.3) || !gs_color_space_is_PSCIE(pcs_in) ) { pcs = pcs_in; } else { pcs = pcs_in; /* The snippet below creates an ICC equivalent profile for the PS color space. This is disabled until I add the capability to specify the profile version to ensure compatability with the PDF versions */ #if 0 if (pcs_in->icc_equivalent != NULL) { pcs = pcs_in->icc_equivalent; } else { /* Need to create the equivalent object */ gs_colorspace_set_icc_equivalent((gs_color_space *)pcs_in, &islab, pdev->memory); pcs = pcs_in->icc_equivalent; } #endif } csi = gs_color_space_get_index(pcs); /* Note that if csi is ICC, check to see if this was one of the default substitutes that we introduced for DeviceGray, DeviceRGB or DeviceCMYK. If it is, then just write the default color. Depending upon the flavor of PDF, or other options, we may want to actually have all the colors defined by ICC profiles and not do the following substituion of the Device space. */ if (csi == gs_color_space_index_ICC) { csi = gsicc_get_default_type(pcs->cmm_icc_profile_data); } 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_ICC: /* * 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->cmm_icc_profile_data == NULL || pdev->CompatibilityLevel < 1.3 ) { if (res_name != NULL) return 0; /* Ignore .includecolorspace */ if (pcs->base_space != NULL) { return pdf_color_space_named( pdev, pvalue, ppranges, pcs->base_space, pcsn, by_name, NULL, 0); } else { /* Base space is NULL, use appropriate device space */ switch( cs_num_components(pcs) ) { case 1: cos_c_string_value(pvalue, pcsn->DeviceGray); return 0; case 3: cos_c_string_value(pvalue, pcsn->DeviceRGB); return 0; case 4: cos_c_string_value(pvalue, pcsn->DeviceCMYK); return 0; default: break; } } } 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_ICC: 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->PreserveDeviceN) return_error(gs_error_rangecheck); 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_named(pdev, &v_separation, NULL, csa->cspace, pcsn, false, NULL, 0); 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; pres_attributes->where_used |= pdev->used_mask; 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: if (!pdev->PreserveSeparation) return_error(gs_error_rangecheck); 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_named(pdev, pvalue, ppranges, pcs->base_space, &pdf_color_space_names, false, NULL, 0)) < 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, resourceColorSpace); } 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; }