Example #1
0
static int
gx_concretize_ICC(
    const gs_client_color * pcc,
    const gs_color_space *  pcs,
    frac *                  pconc,
    const gs_gstate * pgs,
    gx_device *dev)
    {

    gsicc_link_t *icc_link;
    gsicc_rendering_param_t rendering_params;
    unsigned short psrc[GS_CLIENT_COLOR_MAX_COMPONENTS], psrc_cm[GS_CLIENT_COLOR_MAX_COMPONENTS];
    int k;
    unsigned short *psrc_temp;
    int num_des_comps;
    int code;
    cmm_dev_profile_t *dev_profile;

    code = dev_proc(dev, get_profile)(dev, &dev_profile);
    if (code < 0)
        return code;
    num_des_comps = gsicc_get_device_profile_comps(dev_profile);
    /* Define the rendering intents.  */
    rendering_params.black_point_comp = pgs->blackptcomp;
    rendering_params.graphics_type_tag = dev->graphics_type_tag;
    rendering_params.override_icc = false;
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
    rendering_params.rendering_intent = pgs->renderingintent;
    rendering_params.cmm = gsCMM_DEFAULT;
    for (k = 0; k < pcs->cmm_icc_profile_data->num_comps; k++) {
        psrc[k] = (unsigned short) (pcc->paint.values[k]*65535.0);
    }
    /* Get a link from the cache, or create if it is not there. Get 16 bit profile */
    icc_link = gsicc_get_link(pgs, dev, pcs, NULL, &rendering_params, pgs->memory);
    if (icc_link == NULL) {
        #ifdef DEBUG
                gs_warn("Could not create ICC link:  Check profiles");
        #endif
        return -1;
    }
    /* Transform the color */
    if (icc_link->is_identity) {
        psrc_temp = &(psrc[0]);
    } else {
        /* Transform the color */
        psrc_temp = &(psrc_cm[0]);
        (icc_link->procs.map_color)(dev, icc_link, psrc, psrc_temp, 2);
    }
    /* This needs to be optimized */
    for (k = 0; k < num_des_comps; k++){
        pconc[k] = float2frac(((float) psrc_temp[k])/65535.0);
    }
    /* Release the link */
    gsicc_release_link(icc_link);
    return 0;
}
Example #2
0
int
gs_shading_FfGt_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect,
			       const gs_fixed_rect * rect_clip,
			       gx_device * dev, gs_imager_state * pis)
{
    const gs_shading_FfGt_t * const psh = (const gs_shading_FfGt_t *)psh0;
    patch_fill_state_t pfs;
    const gs_shading_mesh_t *pshm = (const gs_shading_mesh_t *)psh;
    shade_coord_stream_t cs;
    int num_bits = psh->params.BitsPerFlag;
    int flag;
    shading_vertex_t va, vb, vc;
    patch_color_t *c, *C[3], *ca, *cb, *cc; /* va.c == ca && vb.c == cb && vc.c == cc always, 
				        provides a non-const access. */
    int code;

    if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s')) {
	vd_get_dc('s');
	vd_set_shift(0, 0);
	vd_set_scale(0.01);
	vd_set_origin(0, 0);
    }
    shade_init_fill_state((shading_fill_state_t *)&pfs,
			  (const gs_shading_t *)psh, dev, pis);
    pfs.Function = pshm->params.Function;
    pfs.rect = *rect_clip;
    code = init_patch_fill_state(&pfs);
    if (code < 0) {
        if (pfs.icclink != NULL) gsicc_release_link(pfs.icclink);
	return code;
    }
    reserve_colors(&pfs, C, 3); /* Can't fail */
    va.c = ca = C[0];
    vb.c = cb = C[1];
    vc.c = cc = C[2];
    shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params,
		    pis);
    /* CET 09-47J.PS SpecialTestI04Test01 does not need the color data alignment. */
    while ((flag = shade_next_flag(&cs, num_bits)) >= 0) {
	switch (flag) {
	    default:
		return_error(gs_error_rangecheck);
	    case 0:
		if ((code = Gt_next_vertex(pshm, &cs, &va, ca)) < 0 ||
		    (code = shade_next_flag(&cs, num_bits)) < 0 ||
		    (code = Gt_next_vertex(pshm, &cs, &vb, cb)) < 0 ||
		    (code = shade_next_flag(&cs, num_bits)) < 0
		    )
		    break;
		goto v2;
	    case 1:
		c = ca;
		va = vb;
		ca = cb;
		vb.c = cb = c;
	    case 2:
		c = cb;
		vb = vc;
		cb = cc;
		vc.c = cc = c;
v2:		if ((code = Gt_next_vertex(pshm, &cs, &vc, cc)) < 0)
		    break;
		if ((code = Gt_fill_triangle(&pfs, &va, &vb, &vc)) < 0)
		    break;
	}
	cs.align(&cs, 8); /* Debugged with 12-14O.PS page 2. */
    }
    if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s'))
	vd_release_dc;
    release_colors(&pfs, pfs.color_stack, 3);
    if (term_patch_fill_state(&pfs))
	return_error(gs_error_unregistered); /* Must not happen. */
    if (!cs.is_eod(&cs))
	return_error(gs_error_rangecheck);
    if (pfs.icclink != NULL) gsicc_release_link(pfs.icclink);
    return code;
}
Example #3
0
int
gs_shading_LfGt_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect,
			       const gs_fixed_rect * rect_clip,
			       gx_device * dev, gs_imager_state * pis)
{
    const gs_shading_LfGt_t * const psh = (const gs_shading_LfGt_t *)psh0;
    patch_fill_state_t pfs;
    const gs_shading_mesh_t *pshm = (const gs_shading_mesh_t *)psh;
    shade_coord_stream_t cs;
    shading_vertex_t *vertex = NULL;
    byte *color_buffer = NULL;
    patch_color_t **color_buffer_ptrs = NULL; /* non-const access to vertex[i].c */
    shading_vertex_t next;
    int per_row = psh->params.VerticesPerRow;
    patch_color_t *c, *cn; /* cn == next.c always, provides a non-contst access. */
    int i, code;

    if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s')) {
	vd_get_dc('s');
	vd_set_shift(0, 0);
	vd_set_scale(0.01);
	vd_set_origin(0, 0);
    }
    shade_init_fill_state((shading_fill_state_t *)&pfs,
			  (const gs_shading_t *)psh, dev, pis);
    pfs.Function = pshm->params.Function;
    pfs.rect = *rect_clip;
    code = init_patch_fill_state(&pfs);
    if (code < 0)
	goto out;
    reserve_colors(&pfs, &cn, 1); /* Can't fail. */
    next.c = cn;
    shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params,
		    pis);
    vertex = (shading_vertex_t *)
	gs_alloc_byte_array(pis->memory, per_row, sizeof(*vertex),
			    "gs_shading_LfGt_render");
    if (vertex == NULL) {
	code = gs_note_error(gs_error_VMerror);
	goto out;
    }
    color_buffer = gs_alloc_bytes(pis->memory, pfs.color_stack_step * per_row, "gs_shading_LfGt_fill_rectangle");
    if (color_buffer == NULL) {
	code = gs_note_error(gs_error_VMerror);
	goto out;
    }
    color_buffer_ptrs = (patch_color_t **)gs_alloc_bytes(pis->memory, 
			    sizeof(patch_color_t *) * per_row, "gs_shading_LfGt_fill_rectangle");
    if (color_buffer_ptrs == NULL) {
	code = gs_note_error(gs_error_VMerror);
	goto out;
    }
    /* CET 09-47K.PS SpecialTestJ02Test05 needs the color data alignment. */
    for (i = 0; i < per_row; ++i) {
	color_buffer_ptrs[i] = (patch_color_t *)(color_buffer + pfs.color_stack_step * i);
	vertex[i].c = color_buffer_ptrs[i];
	if ((code = Gt_next_vertex(pshm, &cs, &vertex[i], color_buffer_ptrs[i])) < 0)
	    goto out;
    }
    while (!seofp(cs.s)) {
	code = Gt_next_vertex(pshm, &cs, &next, cn);
	if (code < 0)
	    goto out;
	for (i = 1; i < per_row; ++i) {
	    code = Gt_fill_triangle(&pfs, &vertex[i - 1], &vertex[i], &next);
	    if (code < 0)
		goto out;
	    c = color_buffer_ptrs[i - 1];
	    vertex[i - 1] = next;
	    color_buffer_ptrs[i - 1] = cn;
	    next.c = cn = c;
	    code = Gt_next_vertex(pshm, &cs, &next, cn);
	    if (code < 0)
		goto out;
	    code = Gt_fill_triangle(&pfs, &vertex[i], &vertex[i - 1], &next);
	    if (code < 0)
		goto out;
	}
	c = color_buffer_ptrs[per_row - 1];
	vertex[per_row - 1] = next;
	color_buffer_ptrs[per_row - 1] = cn;
	next.c = cn = c;
    }
out:
    if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s'))
	vd_release_dc;
    gs_free_object(pis->memory, vertex, "gs_shading_LfGt_render");
    gs_free_object(pis->memory, color_buffer, "gs_shading_LfGt_render");
    gs_free_object(pis->memory, color_buffer_ptrs, "gs_shading_LfGt_render");
    release_colors(&pfs, pfs.color_stack, 1);
    if (term_patch_fill_state(&pfs))
	return_error(gs_error_unregistered); /* Must not happen. */
    if (pfs.icclink != NULL) gsicc_release_link(pfs.icclink);
    return code;
}
Example #4
0
/*
 * Same as above, but there is no rescale of CIELAB colors.  This is needed
   since the rescale is not needed when the source data is image based.
   The DeviceN image rendering case uses the remap proc vs. the ICC based method
   which handles the remapping itself.
 */
int
gx_remap_ICC_imagelab(const gs_client_color * pcc, const gs_color_space * pcs,
        gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
                gs_color_select_t select)
{
    gsicc_link_t *icc_link;
    gsicc_rendering_param_t rendering_params;
    unsigned short psrc[GS_CLIENT_COLOR_MAX_COMPONENTS], psrc_cm[GS_CLIENT_COLOR_MAX_COMPONENTS];
    unsigned short *psrc_temp;
    frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS];
    int k,i;
    int num_des_comps;
    int code;
    cmm_dev_profile_t *dev_profile;

    code = dev_proc(dev, get_profile)(dev, &dev_profile);
    if (code < 0)
        return code;
    num_des_comps = gsicc_get_device_profile_comps(dev_profile);
    rendering_params.black_point_comp = pgs->blackptcomp;
    rendering_params.graphics_type_tag = dev->graphics_type_tag;
    rendering_params.override_icc = false;
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
    rendering_params.rendering_intent = pgs->renderingintent;
    rendering_params.cmm = gsCMM_DEFAULT;
    /* Need to clear out psrc_cm in case we have separation bands that are
       not color managed */
    memset(psrc_cm, 0, sizeof(unsigned short)*GS_CLIENT_COLOR_MAX_COMPONENTS);

    for (k = 0; k < pcs->cmm_icc_profile_data->num_comps; k++)
        psrc[k] = (unsigned short) (pcc->paint.values[k]*65535.0);

    /* Get a link from the cache, or create if it is not there. Need to get 16 bit profile */
    icc_link = gsicc_get_link(pgs, dev, pcs, NULL, &rendering_params, pgs->memory);
    if (icc_link == NULL) {
        #ifdef DEBUG
                gs_warn("Could not create ICC link:  Check profiles");
        #endif
        return -1;
    }
    if (icc_link->is_identity) {
        psrc_temp = &(psrc[0]);
    } else {
        /* Transform the color */
        psrc_temp = &(psrc_cm[0]);
        (icc_link->procs.map_color)(dev, icc_link, psrc, psrc_temp, 2);
    }
    /* Release the link */
    gsicc_release_link(icc_link);
    /* Now do the remap for ICC which amounts to the alpha application
       the transfer function and potentially the halftoning */
    /* Right now we need to go from unsigned short to frac.  I really
       would like to avoid this sort of stuff.  That will come. */
    for ( k = 0; k < num_des_comps; k++){
        conc[k] = ushort2frac(psrc_temp[k]);
    }
    gx_remap_concrete_ICC(conc, pcs, pdc, pgs, dev, select);

    /* Save original color space and color info into dev color */
    i = pcs->cmm_icc_profile_data->num_comps;
    for (i--; i >= 0; i--)
        pdc->ccolor.paint.values[i] = pcc->paint.values[i];
    pdc->ccolor_valid = true;
    return 0;
}
Example #5
0
/* Function returns -1 if name not found.  Otherwise transform the color. */
int
gsicc_transform_named_color(float tint_value, byte *color_name, uint name_size,
                            gx_color_value device_values[],
                            const gs_imager_state *pis, gx_device *dev,
                            cmm_profile_t *gs_output_profile,
                            gsicc_rendering_param_t *rendering_params,
                            bool include_softproof)
{

    gsicc_namedcolor_t *namedcolor_data;
    unsigned int num_entries;
    cmm_profile_t *named_profile;
    gsicc_namedcolortable_t *namedcolor_table;
    int k,j;
    float lab[3];
    const char *buffptr;
    int buffer_count;
    int count;
    int code;
    char *pch, *temp_ptr;
    bool done;
    int curr_name_size;
    bool found_match;
    unsigned short psrc[GS_CLIENT_COLOR_MAX_COMPONENTS];
    unsigned short psrc_cm[GS_CLIENT_COLOR_MAX_COMPONENTS];
    unsigned short *psrc_temp;
    float temp;
    unsigned short white_lab[3] = {65535, 32767, 32767};
    gsicc_link_t *icc_link;
    cmm_profile_t *curr_output_profile;

    /* Check if the data that we have has already been generated. */
    if (pis->icc_manager != NULL) {
        if (pis->icc_manager->device_named != NULL) {
            named_profile = pis->icc_manager->device_named;
            if (named_profile->buffer != NULL &&
                named_profile->profile_handle == NULL) {
                /* Create the structure that we will use in searching */
                /*  Note that we do this in non-GC memory since the
                    profile pointer is not GC'd */
                namedcolor_table =
                    (gsicc_namedcolortable_t*) gs_malloc(pis->memory->stable_memory, 1,
                                                    sizeof(gsicc_namedcolortable_t),
                                                    "gsicc_transform_named_color");
                if (namedcolor_table == NULL) return(-1);
                /* Parse buffer and load the structure we will be searching */
                buffptr = (const char*) named_profile->buffer;
                buffer_count = named_profile->buffer_size;
                count = sscanf(buffptr,"%d",&num_entries);
                if (num_entries < 1 || count == 0) {
                    gs_free(pis->memory, namedcolor_table, 1,
                            sizeof(gsicc_namedcolortable_t),
                            "gsicc_transform_named_color");
                    return (-1);
                }
                code = get_to_next_line(&buffptr,&buffer_count);
                if (code < 0) {
                    gs_free(pis->memory,
                            namedcolor_table, 1,
                            sizeof(gsicc_namedcolortable_t),
                            "gsicc_transform_named_color");
                    return (-1);
                }
                namedcolor_data =
                    (gsicc_namedcolor_t*) gs_malloc(pis->memory->stable_memory, num_entries,
                                                    sizeof(gsicc_namedcolor_t),
                                                    "gsicc_transform_named_color");
                if (namedcolor_data == NULL) {
                    gs_free(pis->memory, namedcolor_table, 1,
                            sizeof(gsicc_namedcolortable_t),
                            "gsicc_transform_named_color");
                    return (-1);
                }
                namedcolor_table->number_entries = num_entries;
                namedcolor_table->named_color = namedcolor_data;
                for (k = 0; k < num_entries; k++) {
                    if (k == 0) {
                        pch = strtok(buffptr,",;");
                    } else {
                        pch = strtok(NULL,",;");
                    }
                    /* Remove any /0d /0a stuff from start */
                    temp_ptr = pch;
                    done = 0;
                    while (!done) {
                        if (*temp_ptr == 0x0d || *temp_ptr == 0x0a) {
                            temp_ptr++;
                        } else {
                            done = 1;
                        }
                    }
                    curr_name_size = strlen(temp_ptr);
                    namedcolor_data[k].name_size = curr_name_size;
                    /* +1 for the null */
                    namedcolor_data[k].colorant_name =
                        (char*) gs_malloc(pis->memory->stable_memory,1,name_size+1,
                                        "gsicc_transform_named_color");
                    strncpy(namedcolor_data[k].colorant_name,temp_ptr,
                            namedcolor_data[k].name_size+1);
                    for (j = 0; j < 3; j++) {
                        pch = strtok(NULL,",;");
                        count = sscanf(pch,"%f",&(lab[j]));
                    }
                    lab[0] = lab[0]*65535/100.0;
                    lab[1] = (lab[1] + 128.0)*65535/255;
                    lab[2] = (lab[2] + 128.0)*65535/255;
                    for (j = 0; j < 3; j++) {
                        if (lab[j] > 65535) lab[j] = 65535;
                        if (lab[j] < 0) lab[j] = 0;
                        namedcolor_data[k].lab[j] = (unsigned short) lab[j];
                    }
                    if (code < 0) {
                        gs_free(pis->memory, namedcolor_table, 1,
                                sizeof(gsicc_namedcolortable_t),
                                "gsicc_transform_named_color");
                        gs_free(pis->memory, namedcolor_data, num_entries,
                                sizeof(gsicc_namedcolordata_t),
                                "gsicc_transform_named_color");
                        return (-1);
                    }
                }
                /* Assign to the profile pointer */
                named_profile->profile_handle = namedcolor_table;
            } else {
                if (named_profile->profile_handle != NULL ) {
                    namedcolor_table =
                        (gsicc_namedcolortable_t*) named_profile->profile_handle;
                   num_entries = namedcolor_table->number_entries;
                } else {
                    return(-1);
                }
            }
            /* Search our structure for the color name */
            found_match = false;
            for (k = 0; k < num_entries; k++) {
                if (name_size == namedcolor_table->named_color[k].name_size) {
                    if( strncmp((const char *) namedcolor_table->named_color[k].colorant_name,
                        (const char *) color_name, name_size) == 0) {
                            found_match = true;
                            break;
                    }
                }
            }
            if (found_match) {
                /* Apply tint and push through CMM */
                for (j = 0; j < 3; j++) {
                    temp = (float) namedcolor_table->named_color[k].lab[j] * tint_value
                            + (float) white_lab[j] * (1.0 - tint_value);
                    psrc[j] = (unsigned short) temp;
                }
                if ( gs_output_profile != NULL ) {
                    curr_output_profile = gs_output_profile;
                } else {
                    /* Use the device profile */
                    curr_output_profile = dev->device_icc_profile;
                }
                icc_link = gsicc_get_link_profile(pis, dev,
                                                pis->icc_manager->lab_profile,
                                                curr_output_profile, rendering_params,
                                                pis->memory, false);
                if (icc_link->is_identity) {
                    psrc_temp = &(psrc[0]);
                } else {
                    /* Transform the color */
                    psrc_temp = &(psrc_cm[0]);
                    gscms_transform_color(icc_link, psrc, psrc_temp, 2, NULL);
                }
                gsicc_release_link(icc_link);
                for ( k = 0; k < curr_output_profile->num_comps; k++){
                    device_values[k] = psrc_temp[k];
                }
                return(0);
            } else {
                return (-1);
            }
        }
    }
    return(-1);
}