static void rgb_cs_to_spotn_cm(gx_device * dev, const gs_imager_state *pis, frac r, frac g, frac b, frac out[]) { /* TO_DO_DEVICEN This routine needs to include the effects of the SeparationOrder array */ xcf_device *xdev = (xcf_device *)dev; int n = xdev->separation_names.num_names; gcmmhlink_t link = xdev->rgb_icc_link; int i; if (link != NULL) { unsigned short in[3]; unsigned short tmp[MAX_CHAN]; int outn = xdev->rgb_profile->num_comps_out; in[0] = frac2ushort(r); in[1] = frac2ushort(g); in[2] = frac2ushort(b); gscms_transform_color(dev, link, &(in[0]), &(tmp[0]), 2); for (i = 0; i < outn; i++) out[i] = ushort2frac(tmp[i]); for (; i < n + 4; i++) out[i] = 0; } else { frac cmyk[4]; color_rgb_to_cmyk(r, g, b, pis, cmyk, dev->memory); cmyk_cs_to_spotn_cm(dev, cmyk[0], cmyk[1], cmyk[2], cmyk[3], out); } }
static void cmyk_cs_to_spotn_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { /* TO_DO_DEVICEN This routine needs to include the effects of the SeparationOrder array */ xcf_device *xdev = (xcf_device *)dev; int n = xdev->separation_names.num_names; gcmmhlink_t link = xdev->cmyk_icc_link; int i; if (link != NULL) { unsigned short in[4]; unsigned short tmp[MAX_CHAN]; int outn = xdev->cmyk_profile->num_comps_out; in[0] = frac2ushort(c); in[1] = frac2ushort(m); in[2] = frac2ushort(y); in[3] = frac2ushort(k); gscms_transform_color(dev, link, &(in[0]), &(tmp[0]), 2); for (i = 0; i < outn; i++) out[i] = ushort2frac(tmp[i]); for (; i < n + 4; i++) out[i] = 0; } else { /* If no profile given, assume CMYK */ out[0] = c; out[1] = m; out[2] = y; out[3] = k; for(i = 0; i < n; i++) /* Clear spot colors */ out[4 + i] = 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); }