/* * Construct a new separation color space. */ int gs_cspace_new_Separation( gs_color_space **ppcs, gs_color_space * palt_cspace, gs_memory_t * pmem ) { gs_color_space *pcs; int code; if (palt_cspace == 0 || !palt_cspace->type->can_be_alt_space) return_error(gs_error_rangecheck); pcs = gs_cspace_alloc(pmem, &gs_color_space_type_Separation); if (pcs == NULL) return_error(gs_error_VMerror); pcs->params.separation.map = NULL; code = alloc_device_n_map(&pcs->params.separation.map, pmem, "gs_cspace_build_Separation"); if (code < 0) { gs_free_object(pmem, pcs, "gs_cspace_build_Separation"); return_error(code); } pcs->base_space = palt_cspace; rc_increment_cs(palt_cspace); *ppcs = pcs; return 0; }
/* * Constructor for ICCBased color space. As with the other color space * constructors, this provides only minimal initialization. */ int gs_cspace_build_ICC( gs_color_space ** ppcspace, void * client_data, gs_memory_t * pmem ) { gs_color_space *pcspace = gs_cspace_alloc(pmem, &gs_color_space_type_ICC); *ppcspace = pcspace; return 0; }
RELOC_PTRS_END /* ------ Public procedures ------ */ /* * Create a new DeviceN colorspace. */ int gs_cspace_new_DeviceN( gs_color_space **ppcs, uint num_components, gs_color_space *palt_cspace, gs_memory_t *pmem ) { gs_color_space *pcs; gs_device_n_params *pcsdevn; gs_separation_name *pnames; int code; if (palt_cspace == 0 || !palt_cspace->type->can_be_alt_space) return_error(gs_error_rangecheck); pcs = gs_cspace_alloc(pmem, &gs_color_space_type_DeviceN); if (pcs == NULL) return_error(gs_error_VMerror); pcsdevn = &pcs->params.device_n; pcsdevn->names = NULL; pcsdevn->map = NULL; pcsdevn->colorants = NULL; /* Allocate space for color names list. */ code = alloc_device_n_map(&pcsdevn->map, pmem, "gs_cspace_build_DeviceN"); if (code < 0) { gs_free_object(pmem, pcs, "gs_cspace_new_DeviceN"); return code; } /* Allocate space for color names list. */ pnames = (gs_separation_name *) gs_alloc_byte_array(pmem, num_components, sizeof(gs_separation_name), ".gs_cspace_build_DeviceN(names)"); if (pnames == 0) { gs_free_object(pmem, pcsdevn->map, ".gs_cspace_build_DeviceN(map)"); gs_free_object(pmem, pcs, "gs_cspace_new_DeviceN"); return_error(gs_error_VMerror); } pcs->base_space = palt_cspace; rc_increment_cs(palt_cspace); pcsdevn->names = pnames; pcsdevn->num_components = num_components; *ppcs = pcs; return 0; }
/* * Allocate a color space and its parameter structure. * Return 0 if VMerror, otherwise the parameter structure. * * This is exported for the benefit of gsicc.c */ void * gx_build_cie_space(gs_color_space ** ppcspace, const gs_color_space_type * pcstype, gs_memory_type_ptr_t stype, gs_memory_t * pmem) { gs_color_space *pcspace = gs_cspace_alloc(pmem, pcstype); gs_cie_common_elements_t *pdata; if (pcspace == NULL) return NULL; rc_alloc_struct_1(pdata, gs_cie_common_elements_t, stype, pmem, { gs_free_object(pmem, pcspace, "gx_build_cie_space"); return 0; } , "gx_build_cie_space(data)");
/* This does all the work of setpattern except for the final setcolor. */ int gs_setpatternspace(gs_state * pgs) { int code = 0; if (pgs->in_cachedevice) return_error(gs_error_undefined); if (pgs->color_space->type->index != gs_color_space_index_Pattern) { gs_color_space *pcs; pcs = gs_cspace_alloc(pgs->memory, &gs_color_space_type_Pattern); if (pcs == NULL) return_error(gs_error_VMerror); /* reference to base space shifts from pgs to pcs with no net change */ pcs->base_space = pgs->color_space; pcs->params.pattern.has_base_space = true; pgs->color_space = pcs; cs_full_init_color(pgs->ccolor, pcs); gx_unset_dev_color(pgs); } return code; }
/* Create a DevicePixel color space. */ int gs_cspace_new_DevicePixel(gs_memory_t *mem, gs_color_space **ppcs, int depth) { gs_color_space *pcs; switch (depth) { case 1: case 2: case 4: case 8: case 16: case 24: case 32: break; default: return_error(gs_error_rangecheck); } pcs = gs_cspace_alloc(mem, &gs_color_space_type_DevicePixel); if (pcs == NULL) return_error(gs_error_VMerror); pcs->params.pixel.depth = depth; *ppcs = pcs; return 0; }
/* shfill */ int gs_shfill(gs_gstate * pgs, const gs_shading_t * psh) { /* * shfill is equivalent to filling the current clipping path (or, if * clipping, its bounding box) with the shading, disregarding the * Background if any. In order to produce reasonable high-level output, * we must implement this by calling gs_fill_path. */ gs_pattern2_template_t pat; gs_matrix imat; gs_client_color cc; gs_color_space *pcs; gx_device_color devc; int code; /* Must install the shading color space to allow check_DeviceN_component_names initialize the color component map. */ /* Don't bother with saving the old color space, color, and cie_joint_caches, because .shfill is always called within gsave-grestore - see gs/lib . */ code = gs_setcolorspace(pgs, psh->params.ColorSpace); if (code < 0) return 0; if (psh->params.cie_joint_caches != NULL) { pgs->cie_joint_caches = psh->params.cie_joint_caches; rc_increment(pgs->cie_joint_caches); } gs_pattern2_init(&pat); pat.Shading = psh; gs_make_identity(&imat); code = gs_make_pattern(&cc, (gs_pattern_template_t *)&pat, &imat, pgs, pgs->memory); if (code < 0) return code; code = gs_pattern2_set_shfill(&cc); if (code < 0) return code; pcs = gs_cspace_alloc(pgs->memory, &gs_color_space_type_Pattern); if (pcs == NULL) return_error(gs_error_VMerror); pcs->params.pattern.has_base_space = false; code = pcs->type->remap_color(&cc, pcs, &devc, pgs, pgs->device, gs_color_select_texture); if (code >= 0) { gx_device *dev = pgs->device; bool need_path = !dev_proc(dev, dev_spec_op)(dev, gxdso_pattern_shfill_doesnt_need_path, NULL, 0); if (need_path) { gx_path cpath; gx_path_init_local(&cpath, pgs->memory); code = gx_cpath_to_path(pgs->clip_path, &cpath); if (code >= 0) code = gx_fill_path(&cpath, &devc, pgs, gx_rule_winding_number, pgs->fill_adjust.x, pgs->fill_adjust.y); gx_path_free(&cpath, "gs_shfill"); } else code = gx_fill_path(NULL, &devc, pgs, gx_rule_winding_number, pgs->fill_adjust.x, pgs->fill_adjust.y); } rc_decrement_cs(pcs, "gs_shfill"); gs_pattern_reference(&cc, -1); return code; }
/* Set up the color space information for a bitmap image or pattern. */ int px_image_color_space(gs_image_t *pim, const px_bitmap_params_t *params, const gs_string *palette, const gs_state *pgs) { int depth = params->depth; gs_color_space *pbase_pcs = NULL; gs_color_space *pcs = NULL; bool cie_space = false; int code = 0; switch ( params->color_space ) { case eGray: pbase_pcs = gs_cspace_new_DeviceGray(pgs->memory); pbase_pcs->cmm_icc_profile_data = pgs->icc_manager->default_gray; pbase_pcs->type = &gs_color_space_type_ICC; rc_increment(pbase_pcs->cmm_icc_profile_data); break; case eRGB: pbase_pcs = gs_cspace_new_DeviceRGB(pgs->memory); pbase_pcs->cmm_icc_profile_data = pgs->icc_manager->default_rgb; pbase_pcs->type = &gs_color_space_type_ICC; rc_increment(pbase_pcs->cmm_icc_profile_data); break; case eSRGB: case eCRGB: if ( pl_cspace_init_SRGB(&pbase_pcs, pgs) < 0 ) /* should not happen */ return_error(errorInsufficientMemory); cie_space = true; pbase_pcs->cmm_icc_profile_data = pgs->icc_manager->default_rgb; pbase_pcs->type = &gs_color_space_type_ICC; rc_increment(pbase_pcs->cmm_icc_profile_data); break; default: return_error(errorIllegalAttributeValue); } if (pbase_pcs == NULL) return_error(errorInsufficientMemory); if ( params->indexed ) { pcs = gs_cspace_alloc(pgs->memory, &gs_color_space_type_Indexed); if ( pcs == NULL ) { /* free the base space also */ rc_decrement(pbase_pcs, "px_image_color_space"); return_error(errorInsufficientMemory); } pcs->base_space = pbase_pcs; pcs->params.indexed.hival = (1 << depth) - 1; pcs->params.indexed.lookup.table.size = palette->size; { uint n = palette->size; byte *p = gs_alloc_string(pgs->memory, n, "px_image_color_space(palette)"); if ( p == 0 ) { rc_decrement(pbase_pcs, "px_image_color_space"); return_error(errorInsufficientMemory); } memcpy(p, palette->data, n); pcs->params.indexed.lookup.table.data = p; } pcs->params.indexed.use_proc = 0; } else { pcs = pbase_pcs; } gs_image_t_init(pim, pcs); pim->ColorSpace = pcs; pim->BitsPerComponent = depth; if ( params->indexed ) pim->Decode[1] = (1 << depth) - 1; /* NB - this needs investigation */ if (cie_space && !px_is_currentcolor_pattern(pgs)) { code = pl_setSRGBcolor((gs_state *)pgs, 0.0, 0.0, 0.0); } return code; }