Exemplo n.º 1
0
/* Get the replacement color management link.  It basically needs to store
   the number of components for the source so that we know what we are 
   coming from (e.g. RGB, CMYK, Gray) */
gsicc_link_t*
gsicc_rcm_get_link(const gs_imager_state *pis, gx_device *dev, 
                   gsicc_colorbuffer_t data_cs)
{
    gsicc_link_t *result;
    gsicc_hashlink_t hash;
    rcm_link_t *rcm_link;
    gs_memory_t *mem = dev->memory->non_gc_memory;
    const gx_cm_color_map_procs * cm_procs;
    bool pageneutralcolor = false;
    cmm_dev_profile_t *dev_profile;
    int code;

    /* Need to check if we need to monitor for color */
    if (dev != NULL ) {
        code = dev_proc(dev, get_profile)(dev,  &dev_profile);
        if (code < 0)
            return NULL;
        if (dev_profile != NULL) {
            pageneutralcolor = dev_profile->pageneutralcolor;
        }
     }

    /* If the cm_procs are forwarding due to the overprint device or other
       odd thing, drill down now and get the proper ones */
    if (fwd_uses_fwd_cmap_procs(dev)) {
        cm_procs = fwd_get_target_cmap_procs(dev);
    } else {
        cm_procs = get_color_mapping_procs_subclass(dev);
    }

    hash.rend_hash = gsCMM_REPLACE;
    hash.des_hash = dev->color_info.num_components;
    hash.src_hash = data_cs;
    hash.link_hashcode = data_cs + hash.des_hash * 256 + hash.rend_hash * 4096;

    /* Check the cache for a hit. */
    result = gsicc_findcachelink(hash, pis->icc_link_cache, false, false);
    if (result != NULL) {
        return result;
    }
    /* If not, then lets create a new one.  This may actually return a link if 
       another thread has already created it while we were trying to do so */ 
    if (gsicc_alloc_link_entry(pis->icc_link_cache, &result, hash, false, false)) 
        return result;

    if (result == NULL)
        return result;

    /* Now compute the link contents */
    /* Lock the cache as we alter the procs */
    gx_monitor_enter(pis->icc_link_cache->lock);	

    result->procs.map_buffer = gsicc_rcm_transform_color_buffer;
    result->procs.map_color = gsicc_rcm_transform_color;
    result->procs.free_link = gsicc_rcm_freelink;
    result->hashcode = hash;
    result->is_identity = false;
    rcm_link = (rcm_link_t *) gs_alloc_bytes(mem, sizeof(rcm_link_t),
                                               "gsicc_rcm_get_link");
    if (rcm_link == NULL)
        return NULL;
    result->link_handle = (void*) rcm_link;
    rcm_link->memory = mem;
    rcm_link->num_out = min(dev->color_info.num_components, 
                             GS_CLIENT_COLOR_MAX_COMPONENTS);
    rcm_link->data_cs_in = data_cs;
    rcm_link->cm_procs.map_cmyk = cm_procs->map_cmyk;
    rcm_link->cm_procs.map_rgb = cm_procs->map_rgb;
    rcm_link->cm_procs.map_gray = cm_procs->map_gray;

    switch (data_cs) {
        case gsGRAY:
            rcm_link->num_in = 1;
            break;
        case gsRGB:
        case gsCIELAB:
            rcm_link->num_in = 3;
            break;
        case gsCMYK:
            rcm_link->num_in = 4;
            break;
        default:
            result->procs.free_link(result);
            return NULL;
    }
    /* Likely set if we have something like a table or procs */    
    rcm_link->context = NULL;  

    result->num_input = rcm_link->num_in;
    result->num_output = rcm_link->num_out;
    result->link_handle = rcm_link;
    result->hashcode.link_hashcode = hash.link_hashcode;
    result->hashcode.des_hash = hash.des_hash;
    result->hashcode.src_hash = hash.src_hash;
    result->hashcode.rend_hash = hash.rend_hash;
    result->includes_softproof = false;
    result->includes_devlink = false;
    if (hash.src_hash == hash.des_hash) {
        result->is_identity = true;
    } else {
        result->is_identity = false;
    }
    result->valid = true;

    /* Set up for monitoring non gray color spaces */
    if (pageneutralcolor && data_cs != gsGRAY)
        gsicc_mcm_set_link(result);

    /* Now release any tasks/threads waiting for these contents */
    while (result->num_waiting > 0) {
        gx_semaphore_signal(result->wait);
        result->num_waiting--;
    }
    gx_monitor_leave(pis->icc_link_cache->lock);	/* done with updating, let everyone run */

    return result;
}
Exemplo n.º 2
0
/* Get the link, which is the mapping procedure in this non color managed 
   transformation case. */
gsicc_link_t*
gsicc_nocm_get_link(const gs_imager_state *pis, gx_device *dev, 
                    gs_color_space_index src_index)
{
    gsicc_link_t *result;
    gsicc_hashlink_t hash;
    nocm_link_t *nocm_link;
    gs_memory_t *mem = pis->memory->non_gc_memory;
    const gx_cm_color_map_procs * cm_procs;

    /* If the cm_procs are forwarding due to the overprint device or other
       odd thing, drill down now and get the proper ones */
    if (fwd_uses_fwd_cmap_procs(dev)) {
        cm_procs = fwd_get_target_cmap_procs(dev);
    } else {
        cm_procs = dev_proc(dev, get_color_mapping_procs)(dev);
    }
    /* We will add this to the link cache so that we can avoid the issue
       of black_generation and undercolor removal being GC values.
       Since the link is not GC we would need to copy the contents over
       each time a link was requested.  This could be costly if we had 
       a lot of link requests.  */
    hash.rend_hash = 0;
    hash.des_hash = dev->color_info.num_components;
    hash.src_hash = src_index;
    hash.link_hashcode = src_index + hash.des_hash * 256;

    /* Check the cache for a hit. */
    result = gsicc_findcachelink(hash, pis->icc_link_cache, false, false);
    if (result != NULL) {
        return result;
    }
    /* If not, then lets create a new one.  This may actually return a link if 
       another thread has already created it while we were trying to do so */ 
    if (gsicc_alloc_link_entry(pis->icc_link_cache, &result, hash, false, false)) 
        return result;
    /* Now compute the link contents */
    result->procs.map_buffer = gsicc_nocm_transform_color_buffer;
    result->procs.map_color = gsicc_nocm_transform_color;
    result->procs.free_link = gsicc_nocm_freelink;
    result->hashcode = hash;
    nocm_link = (nocm_link_t *) gs_alloc_bytes(mem, sizeof(nocm_link_t),
                                               "gsicc_nocm_get_link");
    result->link_handle = (void*) nocm_link;
    nocm_link->memory = mem;
    /* Create a dummy imager state and populate the ucr/bg values.  This
       is the only part that we need */ 
    if (pis == NULL || 
       (pis->black_generation == NULL && pis->undercolor_removal == NULL)) {
        nocm_link->pis = NULL;
    } else {
        nocm_link->pis = (gs_imager_state*) 
                          gs_alloc_bytes(mem, sizeof(gs_imager_state), 
                                         "gsicc_nocm_get_link");
        nocm_link->pis->black_generation = (gx_transfer_map*)
                            gsicc_nocm_copy_curve(pis->black_generation, mem); 
        nocm_link->pis->undercolor_removal = (gx_transfer_map*)
                            gsicc_nocm_copy_curve(pis->undercolor_removal, mem); 
    }
    nocm_link->num_out = min(dev->color_info.num_components, 
                             GS_CLIENT_COLOR_MAX_COMPONENTS);
    nocm_link->cm_procs.map_cmyk = cm_procs->map_cmyk;
    nocm_link->cm_procs.map_rgb = cm_procs->map_rgb;
    nocm_link->cm_procs.map_gray = cm_procs->map_gray;
    nocm_link->num_in = src_index;
    if (result != NULL) {
        gsicc_set_link_data(result, nocm_link, NULL, hash, 
                            pis->icc_link_cache->lock, false, false);
    }
    return result;
}