summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gs/Resource/Init/pdf_draw.ps2
-rw-r--r--gs/base/gdevp14.c388
-rw-r--r--gs/base/gdevp14.h3
-rw-r--r--gs/base/gsccolor.h1
-rw-r--r--gs/base/gscms.h40
-rw-r--r--gs/base/gsicc_profilecache.c228
-rw-r--r--gs/base/gsicc_profilecache.h36
-rw-r--r--gs/base/gsicccache.c46
-rw-r--r--gs/base/gsicccache.h5
-rw-r--r--gs/base/gsistate.c20
-rw-r--r--gs/base/gstparam.h4
-rw-r--r--gs/base/gstrans.c206
-rw-r--r--gs/base/gstrans.h2
-rw-r--r--gs/base/gxistate.h5
-rw-r--r--gs/base/lib.mak13
15 files changed, 818 insertions, 181 deletions
diff --git a/gs/Resource/Init/pdf_draw.ps b/gs/Resource/Init/pdf_draw.ps
index 2a29a2947..a8802a236 100644
--- a/gs/Resource/Init/pdf_draw.ps
+++ b/gs/Resource/Init/pdf_draw.ps
@@ -478,7 +478,7 @@ def
/.beginformgroup { % groupdict bbox .beginformgroup -
exch mark exch % bbox mark groupdict
- dup /CS knownoget { resolvecolorspace setgcolorspace } if
+ dup /CS knownoget { resolvecolorspace dup setgcolorspace /CS exch 3 2 roll} if
dup /I knownoget { /Isolated exch 3 2 roll } if
dup /K knownoget { /Knockout exch 3 2 roll } if
pop .dicttomark
diff --git a/gs/base/gdevp14.c b/gs/base/gdevp14.c
index acfb6021c..dec524f42 100644
--- a/gs/base/gdevp14.c
+++ b/gs/base/gdevp14.c
@@ -50,6 +50,7 @@
#include "gzcpath.h"
#include "gxpaint.h"
#include "gsiccmanage.h"
+#include "gsicccache.h"
/* Visual trace options : set one to 1. */
#define VD_PAINT_MASK 0
@@ -90,9 +91,9 @@ gs_private_st_ptrs2(st_pdf14_ctx, pdf14_ctx, "pdf14_ctx",
pdf14_ctx_enum_ptrs, pdf14_ctx_reloc_ptrs,
stack, maskbuf);
-gs_private_st_ptrs1(st_pdf14_clr, pdf14_parent_color_t, "pdf14_clr",
+gs_private_st_ptrs2(st_pdf14_clr, pdf14_parent_color_t, "pdf14_clr",
pdf14_clr_enum_ptrs, pdf14_clr_reloc_ptrs,
- previous);
+ previous, icc_profile);
/* ------ The device descriptors ------ */
@@ -244,7 +245,7 @@ static int pdf14_custom_put_image(gx_device * dev, gs_imager_state * pis,
/* Used to alter device color mapping procs based upon group or softmask color space */
static int pdf14_update_device_color_procs(gx_device *dev,
gs_transparency_color_t group_color,
- gs_imager_state *pis);
+ gs_imager_state *pis, cmm_profile_t *iccprofile);
/* Used to alter device color mapping procs based upon group or softmask color space */
@@ -452,6 +453,7 @@ pdf14_buf_new(gs_int_rect *rect, bool has_alpha_g, bool has_shape, bool idle,
/* yet another plane */
pdf14_buf *result;
+ pdf14_parent_color_t *new_parent_color;
int rowstride = (rect->q.x - rect->p.x + 3) & -4;
int height = (rect->q.y - rect->p.y);
int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0);
@@ -479,9 +481,17 @@ pdf14_buf_new(gs_int_rect *rect, bool has_alpha_g, bool has_shape, bool idle,
result->maskbuf = NULL;
result->idle = idle;
result->mask_id = 0;
- result->parent_color_info_procs.get_cmap_procs = NULL;
- result->parent_color_info_procs.parent_color_mapping_procs = NULL;
- result->parent_color_info_procs.parent_color_comp_index = NULL;
+
+ new_parent_color = gs_alloc_struct(memory, pdf14_parent_color_t, &st_pdf14_clr,
+ "pdf14_buf_new");
+
+ result->parent_color_info_procs = new_parent_color;
+
+ result->parent_color_info_procs->get_cmap_procs = NULL;
+ result->parent_color_info_procs->parent_color_mapping_procs = NULL;
+ result->parent_color_info_procs->parent_color_comp_index = NULL;
+ result->parent_color_info_procs->icc_profile = NULL;
+ result->parent_color_info_procs->previous = NULL;
if (height <= 0 || idle) {
/* Empty clipping - will skip all drawings. */
@@ -514,6 +524,7 @@ pdf14_buf_free(pdf14_buf *buf, gs_memory_t *memory)
{
gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
gs_free_object(memory, buf->data, "pdf14_buf_free");
+ gs_free_object(memory, buf->parent_color_info_procs, "pdf14_buf_free");
gs_free_object(memory, buf, "pdf14_buf_free");
}
@@ -670,8 +681,9 @@ pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect,
}
static int
-pdf14_pop_transparency_group(pdf14_ctx *ctx,
- const pdf14_nonseparable_blending_procs_t * pblend_procs, int curr_num_color_comp)
+pdf14_pop_transparency_group(gs_imager_state *pis, pdf14_ctx *ctx,
+ const pdf14_nonseparable_blending_procs_t * pblend_procs, int curr_num_color_comp,
+ cmm_profile_t *curr_icc_profile)
{
pdf14_buf *tos = ctx->stack;
pdf14_buf *nos = tos->saved;
@@ -679,6 +691,13 @@ pdf14_pop_transparency_group(pdf14_ctx *ctx,
int x0, x1, y0, y1;
byte *new_data_buf;
int num_noncolor_planes, new_num_planes;
+ int num_cols, num_rows;
+
+ gsicc_rendering_param_t rendering_params;
+ gsicc_link_t *icc_link;
+ gsicc_bufferdesc_t input_buff_desc;
+ gsicc_bufferdesc_t output_buff_desc;
+
if (nos == NULL)
return_error(gs_error_rangecheck);
@@ -732,7 +751,9 @@ pdf14_pop_transparency_group(pdf14_ctx *ctx,
/* If the color spaces are different and we actually did do a swap of the procs for color */
- if(nos->parent_color_info_procs.num_components != curr_num_color_comp && nos->parent_color_info_procs.parent_color_mapping_procs != NULL){
+ if ( (nos->parent_color_info_procs->num_components != curr_num_color_comp &&
+ nos->parent_color_info_procs->parent_color_mapping_procs != NULL) ||
+ nos->parent_color_info_procs->icc_profile->hashcode != curr_icc_profile->hashcode) {
if (x0 < x1 && y0 < y1) {
@@ -747,7 +768,7 @@ pdf14_pop_transparency_group(pdf14_ctx *ctx,
reuse. Save that for a later optimization. */
num_noncolor_planes = tos->n_planes - curr_num_color_comp;
- new_num_planes = num_noncolor_planes + nos->parent_color_info_procs.num_components;
+ new_num_planes = num_noncolor_planes + nos->parent_color_info_procs->num_components;
new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride*new_num_planes,
"pdf14_buf_new");
if (new_data_buf == NULL)
@@ -765,8 +786,63 @@ pdf14_pop_transparency_group(pdf14_ctx *ctx,
/* later this will be replaced by gscms_transform_color_buffer */
/* This simple function is for planar data only. */
- gs_transform_color_buffer_generic(tos->data,tos->rowstride,tos->planestride,
- curr_num_color_comp,tos->rect,new_data_buf,nos->parent_color_info_procs.num_components,num_noncolor_planes);
+ if (nos->parent_color_info_procs->icc_profile != NULL && curr_icc_profile != NULL){
+
+ /* Use the ICC color management for buffer color conversion */
+
+ /* Define the rendering intents */
+
+ rendering_params.black_point_comp = BP_ON;
+ rendering_params.object_type = GS_IMAGE_TAG;
+ rendering_params.rendering_intent = gsPERCEPTUAL;
+
+ /* Request the ICC link for the transform that we will need to use */
+
+ icc_link = gsicc_get_link_profile(pis, curr_icc_profile,
+ nos->parent_color_info_procs->icc_profile,
+ &rendering_params, pis->memory, false);
+
+ /* If the link is the identity, then we don't need to do any color conversions */
+
+ if (icc_link->is_identity ) {
+
+ memset(new_data_buf, 0, tos->planestride*new_num_planes);
+
+ } else {
+
+ /* Set up the buffer descriptors. Note that pdf14 always has
+ the alpha channels at the back end (last planes). We will just handle that
+ here and let the CMM know nothing about it */
+
+ num_rows = tos->rect.q.y - tos->rect.p.y;
+ num_cols = tos->rect.q.x - tos->rect.p.x;
+
+ gsicc_init_buffer(&input_buff_desc, curr_num_color_comp, 1,
+ false, false, true, tos->planestride, tos->rowstride,
+ num_rows, num_cols);
+
+ gsicc_init_buffer(&output_buff_desc,
+ nos->parent_color_info_procs->num_components, 1,
+ false, false, true, tos->planestride, tos->rowstride,
+ num_rows, num_cols);
+
+ /* Transform the data */
+
+ gscms_transform_color_buffer(icc_link, &input_buff_desc, &output_buff_desc,
+ tos->data, new_data_buf);
+
+ }
+
+ /* Release the link */
+
+ gsicc_release_link(icc_link);
+
+ } else {
+
+ gs_transform_color_buffer_generic(tos->data,tos->rowstride,tos->planestride,
+ curr_num_color_comp,tos->rect,new_data_buf,nos->parent_color_info_procs->num_components,num_noncolor_planes);
+
+ }
/* Free the old object */
@@ -792,8 +868,8 @@ pdf14_pop_transparency_group(pdf14_ctx *ctx,
/* compose */
pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
- nos->parent_color_info_procs.isadditive,
- nos->parent_color_info_procs.parent_blending_procs);
+ nos->parent_color_info_procs->isadditive,
+ nos->parent_color_info_procs->parent_blending_procs);
}
@@ -1699,7 +1775,8 @@ pdf14_tile_pattern_fill(gx_device * pdev, const gs_imager_state * pis,
/* pop our transparency group which will force the blending */
- code = pdf14_pop_transparency_group(p14dev->ctx, p14dev->blend_procs, p14dev->color_info.num_components);
+ code = pdf14_pop_transparency_group(pis, p14dev->ctx, p14dev->blend_procs, p14dev->color_info.num_components,
+ pis->icc_manager->device_profile);
}
@@ -2388,7 +2465,7 @@ pdf14_begin_transparency_group(gx_device *dev,
The exception would be if we are in doing the group for a soft mask */
if (!sep_target) {
- code = pdf14_update_device_color_procs(dev,group_color,pis);
+ code = pdf14_update_device_color_procs(dev,group_color,pis,ptgp->iccprofile);
} else {
code = 0;
group_color_numcomps = pdev->color_info.num_components;
@@ -2430,6 +2507,7 @@ pdf14_end_transparency_group(gx_device *dev,
pdf14_device *pdev = (pdf14_device *)dev;
int code;
pdf14_parent_color_t *parent_color;
+ cmm_profile_t *curr_device_profile = pis->icc_manager->device_profile;
if_debug0('v', "[v]pdf14_end_transparency_group\n");
vd_get_dc('c');
@@ -2437,42 +2515,41 @@ pdf14_end_transparency_group(gx_device *dev,
vd_set_scale(0.01);
vd_set_origin(0, 0);
vd_erase(RGB(192, 192, 192));
- code = pdf14_pop_transparency_group(pdev->ctx, pdev->blend_procs,pdev->color_info.num_components);
+ code = pdf14_pop_transparency_group(pis, pdev->ctx, pdev->blend_procs,pdev->color_info.num_components, curr_device_profile);
/* May need to reset some color stuff related
* to a mismatch between the parents color space
* and the group blending space */
- parent_color = &(pdev->ctx->stack->parent_color_info_procs);
+ parent_color = pdev->ctx->stack->parent_color_info_procs;
if (!(parent_color->parent_color_mapping_procs == NULL &&
parent_color->parent_color_comp_index == NULL)) {
- pis->get_cmap_procs = parent_color->get_cmap_procs;
- gx_set_cmap_procs(pis, dev);
-
- pdev->procs.get_color_mapping_procs = parent_color->parent_color_mapping_procs;
- pdev->procs.get_color_comp_index = parent_color->parent_color_comp_index;
- pdev->color_info.polarity = parent_color->polarity;
- pdev->color_info.num_components = parent_color->num_components;
- pdev->blend_procs = parent_color->parent_blending_procs;
- pdev->ctx->additive = parent_color->isadditive;
- pdev->pdf14_procs = parent_color->unpack_procs;
- pdev->color_info.depth = parent_color->depth;
-
- parent_color->get_cmap_procs = NULL;
- parent_color->parent_color_comp_index = NULL;
- parent_color->parent_color_mapping_procs = NULL;
- }
-
-
-
-
-
-
+ pis->get_cmap_procs = parent_color->get_cmap_procs;
+ gx_set_cmap_procs(pis, dev);
+ pdev->procs.get_color_mapping_procs = parent_color->parent_color_mapping_procs;
+ pdev->procs.get_color_comp_index = parent_color->parent_color_comp_index;
+ pdev->color_info.polarity = parent_color->polarity;
+ pdev->color_info.num_components = parent_color->num_components;
+ pdev->blend_procs = parent_color->parent_blending_procs;
+ pdev->ctx->additive = parent_color->isadditive;
+ pdev->pdf14_procs = parent_color->unpack_procs;
+ pdev->color_info.depth = parent_color->depth;
+
+ if (parent_color->icc_profile != NULL){
+ rc_decrement(pis->icc_manager->device_profile,"pdf14_end_transparency_group");
+ pis->icc_manager->device_profile = parent_color->icc_profile;
+ }
+
+ parent_color->get_cmap_procs = NULL;
+ parent_color->parent_color_comp_index = NULL;
+ parent_color->parent_color_mapping_procs = NULL;
+ parent_color->icc_profile = NULL;
+ }
vd_release_dc;
return code;
@@ -2482,13 +2559,13 @@ pdf14_end_transparency_group(gx_device *dev,
static int
pdf14_update_device_color_procs(gx_device *dev,
gs_transparency_color_t group_color,
- gs_imager_state *pis)
+ gs_imager_state *pis, cmm_profile_t *iccprofile)
{
pdf14_device *pdevproto;
pdf14_device *pdev = (pdf14_device *)dev;
const pdf14_procs_t *new_14procs;
- pdf14_parent_color_t *parent_color_info = &(pdev->ctx->stack->parent_color_info_procs);
+ pdf14_parent_color_t *parent_color_info = pdev->ctx->stack->parent_color_info_procs;
gx_color_polarity_t new_polarity;
int new_num_comps;
bool new_additive;
@@ -2527,7 +2604,6 @@ pdf14_update_device_color_procs(gx_device *dev,
new_14procs = &gray_pdf14_procs;
new_depth = 8;
-
break;
case DEVICE_RGB:
@@ -2553,6 +2629,53 @@ pdf14_update_device_color_procs(gx_device *dev,
break;
+ case ICC:
+
+ /* We need to store the ICC profile */
+
+ new_num_comps = iccprofile->num_comps;
+ new_depth = new_num_comps * 8;
+
+ if (new_num_comps == 4) {
+
+ new_additive = false;
+ new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
+
+ } else {
+
+ new_additive = true;
+ new_polarity = GX_CINFO_POLARITY_ADDITIVE;
+
+ }
+
+ switch (new_num_comps) {
+
+ case 1:
+
+ pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
+ new_14procs = &gray_pdf14_procs;
+
+ break;
+
+ case 3:
+
+ pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
+ new_14procs = &rgb_pdf14_procs;
+
+ break;
+
+ case 4:
+
+ pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
+ new_14procs = &cmyk_pdf14_procs;
+
+ break;
+
+ }
+
+
+ break;
+
default:
return_error(gs_error_rangecheck);
break;
@@ -2576,6 +2699,12 @@ pdf14_update_device_color_procs(gx_device *dev,
parent_color_info->unpack_procs = pdev->pdf14_procs;
parent_color_info->depth = pdev->color_info.depth;
+ /* Don't increment the space since we are going to remove it from the
+ ICC manager anyway */
+ if (group_color == ICC && iccprofile != NULL){
+ parent_color_info->icc_profile = pis->icc_manager->device_profile;
+ }
+
/* Set new information */
pis->get_cmap_procs = pdf14_get_cmap_procs_group;
@@ -2591,6 +2720,15 @@ pdf14_update_device_color_procs(gx_device *dev,
pdev->pdf14_procs = new_14procs;
pdev->color_info.depth = new_depth;
+ /* If the CS was ICC based, we need to update the device ICC profile
+ in the ICC manager, since that is the profile that is used for the
+ PDF14 device */
+
+ if (group_color == ICC && iccprofile != NULL){
+ pis->icc_manager->device_profile = iccprofile;
+ rc_increment(parent_color_info->icc_profile);
+ }
+
return(1); /* Lets us detect that we did do an update */
}
@@ -2614,6 +2752,25 @@ pdf14_update_device_color_procs_push_c(gx_device *dev,
int new_num_comps;
bool new_additive;
byte new_depth;
+ gs_state *pgs;
+ cmm_profile_t *cmm_icc_profile_data;
+
+ if (pis->is_gstate) {
+
+ pgs = (gs_state *)pis;
+ cmm_icc_profile_data = pgs->color_space->cmm_icc_profile_data;
+
+ } else {
+
+ pgs = NULL;
+ cmm_icc_profile_data = NULL;
+
+ if (group_color == ICC ) {
+ return gs_rethrow(gs_error_undefinedresult,
+ "Missing ICC data");
+ }
+
+ }
if_debug0('v', "[v]pdf14_update_device_color_procs_push_c\n");
@@ -2632,6 +2789,8 @@ pdf14_update_device_color_procs_push_c(gx_device *dev,
Remember that only isolated groups can have color spaces
that are different than their parent. */
+
+
update_color_info = false;
switch (group_color) {
@@ -2684,6 +2843,55 @@ pdf14_update_device_color_procs_push_c(gx_device *dev,
break;
+ case ICC:
+
+ /* Check if the profile is different. */
+
+ if (pis->icc_manager->device_profile->hashcode != cmm_icc_profile_data->hashcode)
+ {
+
+ update_color_info = true;
+ new_num_comps = cmm_icc_profile_data->num_comps;
+ new_depth = cmm_icc_profile_data->num_comps*8;
+
+ switch (new_num_comps) {
+
+ case 1:
+
+ new_polarity = GX_CINFO_POLARITY_ADDITIVE;
+ new_additive = true;
+ pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
+ new_14procs = &gray_pdf14_procs;
+ break;
+
+ case 3:
+
+ new_polarity = GX_CINFO_POLARITY_ADDITIVE;
+ new_additive = true;
+ pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
+ new_14procs = &rgb_pdf14_procs;
+ break;
+
+ case 4:
+
+ new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
+ new_additive = false;
+ pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
+ new_14procs = &cmyk_pdf14_procs;
+ break;
+
+ default:
+
+ return gs_rethrow(gs_error_undefinedresult,
+ "ICC Number of colorants illegal");
+
+ }
+
+ }
+
+
+ break;
+
default:
return_error(gs_error_rangecheck);
break;
@@ -2713,7 +2921,17 @@ pdf14_update_device_color_procs_push_c(gx_device *dev,
cldev->clist_color_info.polarity = pdev->color_info.polarity;
cldev->clist_color_info.num_components = pdev->color_info.num_components;
+ /* For the ICC profiles, we want to update the ICC profile for the
+ device in the ICC manager. We already stored in in pdf14_parent_color_t.
+ That will be stored in the clist and restored during the reading phase */
+ if (group_color == ICC) {
+
+ rc_decrement_only(pis->icc_manager->device_profile, "pdf14_update_device_color_procs_push_c");
+ pis->icc_manager->device_profile = cmm_icc_profile_data;
+ rc_increment(cmm_icc_profile_data);
+
+ }
if (pdev->ctx)
{
@@ -2808,9 +3026,8 @@ pdf14_push_parent_color(gx_device *dev, const gs_imager_state *pis)
/* Allocate a new one */
- new_parent_color = gs_alloc_struct(dev->memory, pdf14_parent_color_t,&st_pdf14_clr,
+ new_parent_color = gs_alloc_struct(dev->memory, pdf14_parent_color_t, &st_pdf14_clr,
"pdf14_clr_new");
-
/* Link to old one */
new_parent_color->previous = pdev->trans_group_parent_cmap_procs;
@@ -2831,6 +3048,11 @@ pdf14_push_parent_color(gx_device *dev, const gs_imager_state *pis)
new_parent_color->num_components = pdev->color_info.num_components;
new_parent_color->unpack_procs = pdev->pdf14_procs;
new_parent_color->depth = pdev->color_info.depth;
+
+ /* The ICC manager has the ICC profile for the device */
+
+ new_parent_color->icc_profile = pis->icc_manager->device_profile;
+ rc_increment(pis->icc_manager->device_profile);
/* isadditive is only used in ctx */
if (pdev->ctx)
@@ -2937,10 +3159,9 @@ pdf14_begin_transparency_mask(gx_device *dev,
}
-
/* Always update the color mapping procs. Otherwise we end up
fowarding to the target device. */
- code = pdf14_update_device_color_procs(dev,group_color,pis);
+ code = pdf14_update_device_color_procs(dev,group_color,pis,ptmp->iccprofile);
if (code < 0)
return code;
@@ -2971,7 +3192,7 @@ pdf14_end_transparency_mask(gx_device *dev, gs_imager_state *pis,
if (pdev->ctx->stack != NULL ) {
- parent_color = &(pdev->ctx->stack->parent_color_info_procs);
+ parent_color = pdev->ctx->stack->parent_color_info_procs;
if (!(parent_color->parent_color_mapping_procs == NULL &&
parent_color->parent_color_comp_index == NULL)) {
@@ -3779,12 +4000,16 @@ gs_pdf14_device_push(gs_memory_t *mem, gs_imager_state * pis,
* entire gs_pdf14trans_s structure.
*/
#define private_st_gs_pdf14trans_t()\
- gs_private_st_ptrs1(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
- st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function)
+ gs_private_st_ptrs2(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
+ st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function, params.iccprofile)
+
+
/* GC descriptor for gs_pdf14trans_t */
private_st_gs_pdf14trans_t();
+
+
/*
* Check for equality of two PDF 1.4 transparency compositor objects.
*
@@ -4599,25 +4824,59 @@ get_pdf14_clist_device_proto(gx_device * dev, pdf14_clist_device ** pdevproto,
*ptempdevproto = **pdevproto;
ptempdevproto->color_info.max_components = 1;
ptempdevproto->color_info.num_components = ptempdevproto->color_info.max_components;
+
+ if (dev->color_info.icc_profile == '\0'){
+ strcpy(&(ptempdevproto->color_info.icc_profile[0]), DEFAULT_GRAY_ICC);
+ } else {
+ strcpy(&(ptempdevproto->color_info.icc_profile[0]), dev->color_info.icc_profile);
+ }
+
*pdevproto = ptempdevproto;
break;
+
case PDF14_DeviceRGB:
+
*pdevproto = (pdf14_clist_device *)&pdf14_clist_RGB_device;
+ *ptempdevproto = **pdevproto;
+
+ if (dev->color_info.icc_profile == '\0'){
+ strcpy(&(ptempdevproto->color_info.icc_profile[0]), DEFAULT_RGB_ICC);
+ } else {
+ strcpy(&(ptempdevproto->color_info.icc_profile[0]), dev->color_info.icc_profile);
+ }
+
+ *pdevproto = ptempdevproto;
+
break;
+
case PDF14_DeviceCMYK:
+
*pdevproto = (pdf14_clist_device *)&pdf14_clist_CMYK_device;
- break;
+ *ptempdevproto = **pdevproto;
+
+ if (dev->color_info.icc_profile == '\0'){
+ strcpy(&(ptempdevproto->color_info.icc_profile[0]), DEFAULT_CMYK_ICC);
+ } else {
+ strcpy(&(ptempdevproto->color_info.icc_profile[0]), dev->color_info.icc_profile);
+ }
+
+ *pdevproto = ptempdevproto;
+
+ break;
+
case PDF14_DeviceCMYKspot:
+
*pdevproto = (pdf14_clist_device *)&pdf14_clist_CMYKspot_device;
- *pdevproto = (pdf14_clist_device *)&pdf14_clist_custom_device;
+ *ptempdevproto = **pdevproto;
+
/*
* The number of components for the PDF14 device is the sum
* of the process components and the number of spot colors
* for the page.
*/
+
if (pdf14pct->params.num_spot_colors >= 0) {
- *ptempdevproto = **pdevproto;
ptempdevproto->devn_params.page_spot_colors =
pdf14pct->params.num_spot_colors;
ptempdevproto->color_info.num_components =
@@ -4627,9 +4886,18 @@ get_pdf14_clist_device_proto(gx_device * dev, pdf14_clist_device ** pdevproto,
ptempdevproto->color_info.max_components)
ptempdevproto->color_info.num_components =
ptempdevproto->color_info.max_components;
- *pdevproto = ptempdevproto;
- }
+ }
+
+ if (dev->color_info.icc_profile == '\0'){
+ strcpy(&(ptempdevproto->color_info.icc_profile[0]), DEFAULT_CMYK_ICC);
+ } else {
+ strcpy(&(ptempdevproto->color_info.icc_profile[0]), dev->color_info.icc_profile);
+ }
+
+ *pdevproto = ptempdevproto;
+
break;
+
case PDF14_DeviceCustom:
/*
* We are using the output device's process color model. The
@@ -4638,7 +4906,15 @@ get_pdf14_clist_device_proto(gx_device * dev, pdf14_clist_device ** pdevproto,
*/
*ptempdevproto = pdf14_clist_custom_device;
ptempdevproto->color_info = dev->color_info;
- *pdevproto = ptempdevproto;
+
+ if (dev->color_info.icc_profile == '\0'){
+ strcpy(&(ptempdevproto->color_info.icc_profile[0]), DEFAULT_CMYK_ICC);
+ } else {
+ strcpy(&(ptempdevproto->color_info.icc_profile[0]), dev->color_info.icc_profile);
+ }
+
+ *pdevproto = ptempdevproto;
+
break;
default: /* Should not occur */
return_error(gs_error_rangecheck);
diff --git a/gs/base/gdevp14.h b/gs/base/gdevp14.h
index 374b0c7e5..9886635bb 100644
--- a/gs/base/gdevp14.h
+++ b/gs/base/gdevp14.h
@@ -81,6 +81,7 @@ struct pdf14_parent_color_s {
int (*parent_color_comp_index)(gx_device *, const char *, int, int);
const pdf14_procs_t * unpack_procs;
const pdf14_nonseparable_blending_procs_t * parent_blending_procs;
+ cmm_profile_t *icc_profile;
pdf14_parent_color_t *previous;
};
@@ -119,7 +120,7 @@ struct pdf14_buf_s {
gs_transparency_mask_subtype_t SMask_SubType;
uint mask_id;
- pdf14_parent_color_t parent_color_info_procs;
+ pdf14_parent_color_t *parent_color_info_procs;
gs_transparency_color_t color_space; /* Different groups can have different spaces for blending */
};
diff --git a/gs/base/gsccolor.h b/gs/base/gsccolor.h
index 74fa46281..6d5d66ff2 100644
--- a/gs/base/gsccolor.h
+++ b/gs/base/gsccolor.h
@@ -74,6 +74,7 @@ typedef enum {
DEVICE_CMYK,
CIE_XYZ,
DEVICEN,
+ ICC,
UNKNOWN,
OTHER
} gs_transparency_color_t;
diff --git a/gs/base/gscms.h b/gs/base/gscms.h
index 918fc7b68..e269bd755 100644
--- a/gs/base/gscms.h
+++ b/gs/base/gscms.h
@@ -117,7 +117,7 @@ typedef enum {
of the ghostscript color structure. The item is reference counted. */
struct cmm_profile_s {
- void *profile_handle; /* The profile handle to be used in linking */
+ void *profile_handle; /* The profile handle */
unsigned char num_comps; /* number of device dependent values */
bool islab; /* Needed since we want to detect this to avoid
expensive decode on LAB images. Is true
@@ -138,12 +138,50 @@ struct cmm_profile_s {
are reloaded. */
};
+
+
#ifndef cmm_profile_DEFINED
typedef struct cmm_profile_s cmm_profile_t;
#define cmm_profile_DEFINED
#endif
+
+/* A linked list structure for storing profiles in a table in which we
+ can store and refer to from the clist and also when creating icc profiles
+ from ps object. Right now it is not clear to me if we really need a
+ cache in the traditional sense or a list since I believe the number of entries will
+ in general be very small (i.e. there will not be at MOST more than 2 to 3 internal
+ ICC profiles in a file). The default GRAY, RGB, and CMYK profiles are not
+ stored here but are maintained in the ICC manager. This is for profiles
+ that are in the content and for profiles we generate from PS and PDF CIE (NonICC)
+ color spaces. */
+
+typedef struct gsicc_profile_entry_s gsicc_profile_entry_t;
+
+struct gsicc_profile_entry_s {
+
+ cmm_profile_t *profile; /* The profile */
+ gsicc_profile_entry_t *next; /* next profile */
+ gsicc_profile_entry_t *prev; /* previous profile */
+
+};
+
+
+/* ProfileList. The size of the list is limited
+ by max_memory_size. Profiles are added if there
+ is sufficient memory. */
+
+typedef struct gsicc_profile_list_s {
+
+ gsicc_profile_entry_t *icc_profile_entry;
+ int num_entries;
+ rc_header rc;
+ gs_memory_t *memory;
+
+} gsicc_profile_list_t;
+
+
/* These are the types that we can
potentially have linked together
by the CMS. If the CMS does
diff --git a/gs/base/gsicc_profilecache.c b/gs/base/gsicc_profilecache.c
new file mode 100644
index 000000000..66cf599da
--- /dev/null
+++ b/gs/base/gsicc_profilecache.c
@@ -0,0 +1,228 @@
+/* Copyright (C) 2001-2009 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+/* icc profile cache. at this point not really a cache but
+ a double linked list. it is not clear to me yet that we
+ really need to have a real cache. */
+
+#include "std.h"
+#include "stdpre.h"
+#include "gstypes.h"
+#include "gsmemory.h"
+#include "gsstruct.h"
+#include "scommon.h"
+#include "gscms.h"
+#include "gsicc_profilecache.h"
+#include "gserrors.h"
+
+#define ICC_CACHE_MAXPROFILE 50
+
+gs_private_st_ptrs3(st_profile_entry, gsicc_profile_entry_t, "gsicc_profile_entry",
+ profile_entry_enum_ptrs, profile_entry_reloc_ptrs,
+ profile, next, prev);
+
+gs_private_st_ptrs1(st_profile_list, gsicc_profile_list_t, "gsicc_profile_list",
+ profile_list_enum_ptrs, profile_list_reloc_ptrs,
+ icc_profile_entry);
+
+/**
+ * gsicc_cache_new: Allocate a new ICC cache manager
+ * Return value: Pointer to allocated manager, or NULL on failure.
+ **/
+
+gsicc_profile_list_t *
+gsicc_profilelist_new(gs_memory_t *memory)
+{
+
+ gsicc_profile_list_t *result;
+
+ /* We want this to be maintained in stable_memory. It should not be effected by the
+ save and restores */
+
+ result = gs_alloc_struct(memory->stable_memory, gsicc_profile_list_t, &st_profile_list,
+ "gsicc_profilelist_new");
+
+ if ( result == NULL )
+ return(NULL);
+
+ /* rc_init_free(result, memory->stable_memory, 1, rc_gsicc_profile_list_free); */
+
+ result->icc_profile_entry = NULL;
+ result->num_entries = 0;
+ result->memory = memory;
+
+ return(result);
+
+}
+
+static void
+rc_gsicc_profile_list_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
+{
+ /* Ending the list. */
+
+ /* gsicc_profile_list_t *profile_list = (gsicc_profile_list_t * ) ptr_in;
+ int k;
+ gsicc_profile_entry_t *profile_entry;
+
+ profile_entry = gsicc_find_zeroref_list(profile_list);
+
+ for( k = 0; k < profile_list->num_entries; k++){
+
+ if ( profile_entry->next != NULL){
+
+ gsicc_remove_profile(profile_entry,profile_list, mem);
+
+ }
+
+ }
+
+ gs_free_object(mem->stable_memory, profile_list, "rc_gsicc_profile_list_free"); */
+
+}
+
+static void
+gsicc_add_profile(gsicc_profile_list_t *profile_list, cmm_profile_t *profile, gs_memory_t *memory)
+{
+
+ gsicc_profile_entry_t *result, *nextentry;
+
+ /* The profile has to be added in stable memory. We want them
+ to be maintained across the gsave and grestore process */
+
+ result = gs_alloc_struct(memory->stable_memory, gsicc_profile_entry_t, &st_profile_entry,
+ "gsicc_add_profile");
+
+ if (profile_list->icc_profile_entry != NULL){
+
+ /* Add where ever we are right
+ now. Later we may want to
+ do this differently. */
+
+ nextentry = profile_list->icc_profile_entry->next;
+ profile_list->icc_profile_entry->next = result;
+ result->prev = profile_list->icc_profile_entry;
+ result->next = nextentry;
+
+ if (nextentry != NULL){
+
+ nextentry->prev = result;
+
+ }
+
+ } else {
+
+ result->next = NULL;
+ result->prev = NULL;
+ profile_list->icc_profile_entry = result;
+
+ }
+
+ profile_list->num_entries++;
+
+}
+
+
+static cmm_profile_t*
+gsicc_findprofile(int64_t hash, gsicc_profile_list_t *profile_list)
+{
+
+ gsicc_profile_entry_t *curr_pos1,*curr_pos2;
+ bool foundit = 0;
+
+ /* Look through the cache for the hashcode */
+
+ curr_pos1 = profile_list->icc_profile_entry;
+ curr_pos2 = curr_pos1;
+
+ while (curr_pos1 != NULL ){
+
+ if (curr_pos1->profile->hashcode == hash){
+
+ return(curr_pos1->profile);
+
+ }
+
+ curr_pos1 = curr_pos1->prev;
+
+ }
+
+ while (curr_pos2 != NULL ){
+
+ if (curr_pos2->profile->hashcode == hash){
+
+ return(curr_pos2->profile);
+
+ }
+
+ curr_pos2 = curr_pos2->next;
+
+ }
+
+ return(NULL);
+
+
+}
+
+
+/* Find entry with zero ref count and remove it */
+/* may need to lock cache during this time to avoid */
+/* issue in multi-threaded case */
+
+static gsicc_profile_entry_t*
+gsicc_find_zeroref_list(gsicc_profile_list_t *profile_list){
+
+ gsicc_profile_entry_t *curr_pos1,*curr_pos2;
+ bool foundit = 0;
+
+ /* Look through the cache for zero ref count */
+
+ curr_pos1 = profile_list->icc_profile_entry;
+ curr_pos2 = curr_pos1;
+
+ while (curr_pos1 != NULL ){
+
+ curr_pos2 = curr_pos1;
+ curr_pos1 = curr_pos1->prev;
+
+ }
+
+ return(curr_pos2);
+
+}
+
+/* Remove link from cache. Notify CMS and free */
+
+/*
+static void
+gsicc_remove_link(gsicc_link_t *link, gsicc_link_cache_t *icc_cache, gs_memory_t *memory){
+
+
+ gsicc_link_t *prevlink,*nextlink;
+
+ prevlink = link->prevlink;
+ nextlink = link->nextlink;
+
+ if (prevlink != NULL){
+ prevlink->nextlink = nextlink;
+ }
+
+ if (nextlink != NULL){
+ nextlink->prevlink = prevlink;
+ }
+
+ gsicc_link_free(link, memory);
+
+}
+*/
+
+
+
diff --git a/gs/base/gsicc_profilecache.h b/gs/base/gsicc_profilecache.h
new file mode 100644
index 000000000..43adae3c9
--- /dev/null
+++ b/gs/base/gsicc_profilecache.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 2001-2009 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/
+ or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
+ San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
+*/
+
+
+/* Header for the profile cache. Not really a cache in but a double linked
+ list for now. We need to see what is going to work best for this. */
+
+
+#ifndef gsicc_profilecache_INCLUDED
+# define gsicc_profilecache_INCLUDED
+
+
+gsicc_profile_list_t * gsicc_profilelist_new(gs_memory_t *memory);
+
+static void rc_gsicc_profile_list_free(gs_memory_t * mem, void *ptr_in, client_name_t cname);
+
+static void gsicc_add_profile(gsicc_profile_list_t *profile_list,
+ cmm_profile_t *profile, gs_memory_t *memory);
+
+static cmm_profile_t* gsicc_findprofile(int64_t hash, gsicc_profile_list_t *profile_list);
+
+static gsicc_profile_entry_t* gsicc_find_zeroref_list(gsicc_profile_list_t *profile_list);
+
+
+#endif
+
diff --git a/gs/base/gsicccache.c b/gs/base/gsicccache.c
index 4bef3b313..87cbdfa6e 100644
--- a/gs/base/gsicccache.c
+++ b/gs/base/gsicccache.c
@@ -440,26 +440,12 @@ gsicc_remove_link(gsicc_link_t *link, gsicc_link_cache_t *icc_cache, gs_memory_t
}
-/* This is the main function called to obtain a linked transform from the ICC cache
- If the cache has the link ready, it will return it. If not, it will request
- one from the CMS and then return it. We may need to do some cache locking during
- this process to avoid multi-threaded issues (e.g. someone deleting while someone
- is updating a reference count) */
-
gsicc_link_t*
gsicc_get_link(gs_imager_state *pis, gs_color_space *input_colorspace,
gs_color_space *output_colorspace,
gsicc_rendering_param_t *rendering_params, gs_memory_t *memory, bool include_softproof)
{
- gsicc_hashlink_t hash;
- gsicc_link_t *link;
- gcmmhprofile_t link_handle = NULL;
- void **contextptr = NULL;
- gsicc_manager_t *icc_manager = pis->icc_manager;
- gsicc_link_cache_t *icc_cache = pis->icc_cache;
- gcmmhprofile_t *cms_input_profile;
- gcmmhprofile_t *cms_output_profile;
cmm_profile_t *gs_input_profile;
cmm_profile_t *gs_output_profile;
@@ -475,7 +461,6 @@ gsicc_get_link(gs_imager_state *pis, gs_color_space *input_colorspace,
}
-
if ( output_colorspace != NULL ) {
gs_output_profile = output_colorspace->cmm_icc_profile_data;
@@ -487,6 +472,37 @@ gsicc_get_link(gs_imager_state *pis, gs_color_space *input_colorspace,
}
+ return(gsicc_get_link_profile(pis, gs_input_profile, gs_output_profile,
+ rendering_params, memory, include_softproof));
+
+
+
+}
+
+
+
+
+/* This is the main function called to obtain a linked transform from the ICC cache
+ If the cache has the link ready, it will return it. If not, it will request
+ one from the CMS and then return it. We may need to do some cache locking during
+ this process to avoid multi-threaded issues (e.g. someone deleting while someone
+ is updating a reference count) */
+
+gsicc_link_t*
+gsicc_get_link_profile(gs_imager_state *pis, cmm_profile_t *gs_input_profile,
+ cmm_profile_t *gs_output_profile,
+ gsicc_rendering_param_t *rendering_params, gs_memory_t *memory, bool include_softproof)
+{
+
+ gsicc_hashlink_t hash;
+ gsicc_link_t *link;
+ gcmmhprofile_t link_handle = NULL;
+ void **contextptr = NULL;
+ gsicc_manager_t *icc_manager = pis->icc_manager;
+ gsicc_link_cache_t *icc_cache = pis->icc_link_cache;
+ gcmmhprofile_t *cms_input_profile;
+ gcmmhprofile_t *cms_output_profile;
+
/* First compute the hash code for the incoming case */
/* If the output color space is NULL we will use the device profile for the output color space */
diff --git a/gs/base/gsicccache.h b/gs/base/gsicccache.h
index 8db8bb1ce..1131d1bfb 100644
--- a/gs/base/gsicccache.h
+++ b/gs/base/gsicccache.h
@@ -51,6 +51,11 @@ gsicc_link_t* gsicc_get_link(gs_imager_state * pis, gs_color_space *input_color
gs_color_space *output_colorspace,
gsicc_rendering_param_t *rendering_params, gs_memory_t *memory, bool include_softproof);
+gsicc_link_t* gsicc_get_link_profile(gs_imager_state *pis, cmm_profile_t *gs_input_profile,
+ cmm_profile_t *gs_output_profile,
+ gsicc_rendering_param_t *rendering_params, gs_memory_t *memory, bool include_softproof);
+
+
void gsicc_release_link(gsicc_link_t *icclink);
diff --git a/gs/base/gsistate.c b/gs/base/gsistate.c
index dc54a8c40..d6a4c38bf 100644
--- a/gs/base/gsistate.c
+++ b/gs/base/gsistate.c
@@ -65,8 +65,9 @@ ENUM_PTRS_BEGIN(imager_state_enum_ptrs)
ENUM_PTR(1, gs_imager_state, transparency_stack);
ENUM_PTR(2, gs_imager_state, trans_device);
ENUM_PTR(3, gs_imager_state, icc_manager);
- ENUM_PTR(4, gs_imager_state, icc_cache);
-#define E1(i,elt) ENUM_PTR(i+5,gs_imager_state,elt);
+ ENUM_PTR(4, gs_imager_state, icc_link_cache);
+ ENUM_PTR(5, gs_imager_state, icc_profile_cache);
+#define E1(i,elt) ENUM_PTR(i+6,gs_imager_state,elt);
gs_cr_state_do_ptrs(E1)
#undef E1
ENUM_PTRS_END
@@ -77,7 +78,8 @@ static RELOC_PTRS_BEGIN(imager_state_reloc_ptrs)
RELOC_PTR(gs_imager_state, transparency_stack);
RELOC_PTR(gs_imager_state, trans_device);
RELOC_PTR(gs_imager_state, icc_manager);
- RELOC_PTR(gs_imager_state, icc_cache);
+ RELOC_PTR(gs_imager_state, icc_link_cache);
+ RELOC_PTR(gs_imager_state, icc_profile_cache);
#define R1(i,elt) RELOC_PTR(gs_imager_state,elt);
gs_cr_state_do_ptrs(R1)
#undef R1
@@ -132,8 +134,9 @@ gs_imager_state_initialize(gs_imager_state * pis, gs_memory_t * mem)
pis->have_pattern_streams = false;
pis->devicergb_cs = gs_cspace_new_DeviceRGB(mem);
pis->devicecmyk_cs = gs_cspace_new_DeviceCMYK(mem);
- pis->icc_cache = gsicc_cache_new(pis->memory);
+ pis->icc_link_cache = gsicc_cache_new(pis->memory);
pis->icc_manager = gsicc_manager_new(pis->memory);
+ pis->icc_profile_cache = gsicc_profilelist_new(pis->memory);
return 0;
}
@@ -172,7 +175,8 @@ gs_imager_state_copied(gs_imager_state * pis)
rc_increment(pis->cie_joint_caches);
rc_increment(pis->devicergb_cs);
rc_increment(pis->devicecmyk_cs);
- rc_increment(pis->icc_cache);
+ rc_increment(pis->icc_link_cache);
+ rc_increment(pis->icc_profile_cache);
rc_increment(pis->icc_manager);
}
@@ -197,7 +201,8 @@ gs_imager_state_pre_assign(gs_imager_state *pto, const gs_imager_state *pfrom)
RCCOPY(halftone);
RCCOPY(devicergb_cs);
RCCOPY(devicecmyk_cs);
- RCCOPY(icc_cache);
+ RCCOPY(icc_link_cache);
+ RCCOPY(icc_profile_cache);
RCCOPY(icc_manager);
#undef RCCOPY
}
@@ -231,7 +236,8 @@ gs_imager_state_release(gs_imager_state * pis)
RCDECR(halftone);
RCDECR(devicergb_cs);
RCDECR(devicecmyk_cs);
- RCDECR(icc_cache);
+ RCDECR(icc_link_cache);
+ RCDECR(icc_profile_cache);
RCDECR(icc_manager);
#undef RCDECR
}
diff --git a/gs/base/gstparam.h b/gs/base/gstparam.h
index c0bc24f27..409f42827 100644
--- a/gs/base/gstparam.h
+++ b/gs/base/gstparam.h
@@ -19,6 +19,7 @@
#include "gsccolor.h"
#include "gsrefct.h"
+#include "gscspace.h"
/* Define the names of the known blend modes. */
typedef enum {
@@ -87,6 +88,7 @@ typedef struct gs_transparency_group_params_s {
uint mask_id;
int group_color_numcomps;
gs_transparency_color_t group_color;
+ cmm_profile_t *iccprofile; /* The profile */
} gs_transparency_group_params_t;
/* Define the parameter structure for a transparency mask. */
@@ -109,6 +111,7 @@ typedef struct gs_transparency_mask_params_s {
int (*TransferFunction)(floatp in, float *out, void *proc_data);
gs_function_t *TransferFunction_data;
bool replacing;
+ cmm_profile_t *iccprofile; /* The profile */
} gs_transparency_mask_params_t;
#define MASK_TRANSFER_FUNCTION_SIZE 256
@@ -127,6 +130,7 @@ typedef struct gx_transparency_mask_params_s {
bool replacing;
uint mask_id;
byte transfer_fn[MASK_TRANSFER_FUNCTION_SIZE];
+ cmm_profile_t *iccprofile; /* The profile */
} gx_transparency_mask_params_t;
/*
diff --git a/gs/base/gstrans.c b/gs/base/gstrans.c
index 432e2ee7a..fd02f88cd 100644
--- a/gs/base/gstrans.c
+++ b/gs/base/gstrans.c
@@ -28,6 +28,11 @@
#define PUSH_TS 0
+
+gs_private_st_ptrs2(st_gstransparams, gs_transparency_group_params_t, "gs_gstransparams",
+ st_gstransparams_enum_ptrs, st_gstransparams_reloc_ptrs, ColorSpace, iccprofile);
+
+
/* ------ Transparency-related graphics state elements ------ */
int
@@ -171,11 +176,13 @@ gs_state_update_pdf14trans(gs_state * pgs, gs_pdf14trans_params_t * pparams)
void
gs_trans_group_params_init(gs_transparency_group_params_t *ptgp)
{
- ptgp->ColorSpace = 0; /* bogus, but can't do better */
+
+ ptgp->ColorSpace = NULL; /* bogus, but can't do better */
ptgp->Isolated = false;
ptgp->Knockout = false;
ptgp->image_with_SMask = false;
ptgp->mask_id = 0;
+ ptgp->iccprofile = NULL;
}
int
@@ -188,6 +195,7 @@ gs_begin_transparency_group(gs_state *pgs,
gs_imager_state * pis = (gs_imager_state *)pgs;
+
/*
* Put parameters into a compositor parameter and then call the
* create_compositor. This will pass the data to the PDF 1.4
@@ -216,16 +224,10 @@ gs_begin_transparency_group(gs_state *pgs,
} else {
- /* ICC and CIE based color space. Problem right now is that the
- current code does a concretization to the color space
- defined by the CRD. This is not the space that we want
- to blend in. Instead we want all colors to be mapped TO
- the ICC color space. Then when the group is popped they
- should be converted to the parent space.
- That I will need to fix another day with the color changes.
- For now we will punt and set our blending space as the
- concrete space for the ICC space, which is defined by
- the output (or default) CRD. */
+ /* ICC and CIE based color space. With upcoming code changes
+ all CIE based spaces will actually be ICC based spaces and
+ ICC spaces are already concrete. So this will return the
+ ICC color space. */
blend_color_space = cs_concrete_space(pgs->color_space, pis);
@@ -246,31 +248,53 @@ gs_begin_transparency_group(gs_state *pgs,
} else {
- switch (cs_num_components(blend_color_space)) {
- case 1:
- params.group_color = GRAY_SCALE;
- params.group_color_numcomps = 1; /* Need to check */
- break;
- case 3:
- params.group_color = DEVICE_RGB;
- params.group_color_numcomps = 3;
+ 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.
+ MJV ToDo.
+ */
+
+ 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;
+ rc_increment(params.iccprofile);
+
+
+ } else {
+
+ switch (cs_num_components(blend_color_space)) {
+ case 1:
+ params.group_color = GRAY_SCALE;
+ params.group_color_numcomps = 1; /* Need to check */
+ break;
+ case 3:
+ params.group_color = DEVICE_RGB;
+ params.group_color_numcomps = 3;
+ break;
+ case 4:
+ params.group_color = DEVICE_CMYK;
+ params.group_color_numcomps = 4;
break;
- case 4:
- params.group_color = DEVICE_CMYK;
- params.group_color_numcomps = 4;
- break;
- default:
-
- /* We can end up here if we are in
- a deviceN color space and
- we have a sep output device */
+ default:
+
+ /* We can end up here if we are in
+ a deviceN color space and
+ we have a sep output device */
- params.group_color = DEVICEN;
- params.group_color_numcomps = cs_num_components(blend_color_space);
+ params.group_color = DEVICEN;
+ params.group_color_numcomps = cs_num_components(blend_color_space);
- break;
+ break;
- }
+ }
+
+ }
}
@@ -287,6 +311,7 @@ gs_begin_transparency_group(gs_state *pgs,
cs_names[(int)gs_color_space_get_index(ptgp->ColorSpace)]);
else
dputs(" (no CS)");
+
dprintf2(" Isolated = %d Knockout = %d\n",
ptgp->Isolated, ptgp->Knockout);
}
@@ -314,6 +339,7 @@ gx_begin_transparency_group(gs_imager_state * pis, gx_device * pdev,
/* Needed so that we do proper blending */
tgp.group_color = pparams->group_color;
tgp.group_color_numcomps = pparams->group_color_numcomps;
+ tgp.iccprofile = pparams->iccprofile;
pis->opacity.alpha = pparams->opacity.alpha;
pis->shape.alpha = pparams->shape.alpha;
@@ -327,13 +353,15 @@ gx_begin_transparency_group(gs_imager_state * pis, gx_device * pdev,
dlprintf6("[v](0x%lx)gx_begin_transparency_group [%g %g %g %g] Num_grp_clr_comp = %d\n",
(ulong)pis, bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y,pparams->group_color_numcomps);
- if (tgp.ColorSpace)
+ if (tgp.ColorSpace)
dprintf1(" CS = %s",
cs_names[(int)gs_color_space_get_index(tgp.ColorSpace)]);
else
dputs(" (no CS)");
dprintf2(" Isolated = %d Knockout = %d\n",
tgp.Isolated, tgp.Knockout);
+ if (tgp.iccprofile)
+ dprintf(" Have ICC Profile for blending\n");
}
#endif
if (dev_proc(pdev, begin_transparency_group) != 0)
@@ -383,6 +411,8 @@ gs_trans_mask_params_init(gs_transparency_mask_params_t *ptmp,
ptmp->TransferFunction = mask_transfer_identity;
ptmp->TransferFunction_data = 0;
ptmp->replacing = false;
+ ptmp->iccprofile = NULL;
+
}
int
@@ -444,80 +474,54 @@ gs_begin_transparency_mask(gs_state * pgs,
/* Note: This function is called during the c-list writer side. */
+ blend_color_space = pgs->color_space;
- if ( params.SMask_is_CIE && params.subtype == TRANSPARENCY_MASK_Luminosity ){
-
- /* Install Color Space to go to CIEXYZ */
-
- /* int ok;
- ok = gx_cie_to_xyz_alloc2(pgs->color_space,pgs); */ /* quite compiler */
- params.group_color_numcomps = 3; /* CIEXYZ */
-
- /* Mark the proper spaces so that we make
- * the appropriate changes in the device */
+ if ( gs_color_space_is_ICC(blend_color_space) ) {
- params.group_color = CIE_XYZ;
-
- } else {
-
- /* Set the group color type, which may be
- * different than the device type. Note
- we want to check the concrete space due
- to the fact that things are done
- in device space always. */
-
-
- if(!gs_color_space_is_CIE(pgs->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.
+ MJV ToDo.
+ */
- blend_color_space = pgs->color_space;
+ params.group_color = ICC;
+ params.group_color_numcomps =
+ blend_color_space->cmm_icc_profile_data->num_comps;
- } else {
+ /* Get the ICC profile */
- /* ICC or CIE based color space. Problem right now is that the
- current code does a concretization to the color space
- defined by the CRD. This is not the space that we want
- to blend in. Instead we want all colors to be mapped TO
- the ICC color space. Then when the group is popped they
- should be converted to the parent space.
- That I will need to fix another day with the color changes.
- For now we will punt and set our blending space as the
- concrete space for the ICC space, which is defined by
- the output (or default) CRD. */
+ params.iccprofile = blend_color_space->cmm_icc_profile_data;
+ rc_increment(params.iccprofile);
- blend_color_space = cs_concrete_space(pgs->color_space, pis);
- }
+ } else {
- /* For the softmask blend color space, we will always use the above blend_color_space.
- Problems can occur if we go all the way back to the device color space,
- which could be DeviceN for a sep device. Blending to the luminosity
- channel for this case would not be defined. */
- switch (cs_num_components(blend_color_space)) {
+ switch (cs_num_components(blend_color_space)) {
- case 1:
- params.group_color = GRAY_SCALE;
- params.group_color_numcomps = 1; /* Need to check */
- break;
- case 3:
- params.group_color = DEVICE_RGB;
- params.group_color_numcomps = 3;
- break;
- case 4:
- params.group_color = DEVICE_CMYK;
- params.group_color_numcomps = 4;
- break;
- default:
- /* Transparency soft mask spot
- colors are NEVER available.
- We must use the alternate tint
- transform */
- return_error(gs_error_rangecheck);
- break;
+ case 1:
+ params.group_color = GRAY_SCALE;
+ params.group_color_numcomps = 1; /* Need to check */
+ break;
+ case 3:
+ params.group_color = DEVICE_RGB;
+ params.group_color_numcomps = 3;
+ break;
+ case 4:
+ params.group_color = DEVICE_CMYK;
+ params.group_color_numcomps = 4;
+ break;
+ default:
+ /* Transparency soft mask spot
+ colors are NEVER available.
+ We must use the alternate tint
+ transform */
+ return_error(gs_error_rangecheck);
+ break;
- }
+ }
- }
+ }
return gs_state_update_pdf14trans(pgs, &params);
}
@@ -542,6 +546,18 @@ gx_begin_transparency_mask(gs_imager_state * pis, gx_device * pdev,
tmp.idle = pparams->idle;
tmp.replacing = pparams->replacing;
tmp.mask_id = pparams->mask_id;
+
+ if (tmp.group_color == ICC ) {
+
+ tmp.iccprofile = pparams->iccprofile;
+ /* Do I need to ref count here */
+
+ } else {
+
+ tmp.iccprofile = NULL;
+
+ }
+
memcpy(tmp.transfer_fn, pparams->transfer_fn, size_of(tmp.transfer_fn));
if_debug9('v', "[v](0x%lx)gx_begin_transparency_mask [%g %g %g %g]\n\
subtype = %d Background_components = %d Num_grp_clr_comp = %d %s\n",
diff --git a/gs/base/gstrans.h b/gs/base/gstrans.h
index d618a27f3..27342fb4d 100644
--- a/gs/base/gstrans.h
+++ b/gs/base/gstrans.h
@@ -99,6 +99,8 @@ struct gs_pdf14trans_params_s {
bool SMask_is_CIE;
int group_color_numcomps;
gs_transparency_color_t group_color;
+ cmm_profile_t *iccprofile; /* The profile */
+
};
#ifndef gs_pdf14trans_params_DEFINED
diff --git a/gs/base/gxistate.h b/gs/base/gxistate.h
index adae58f97..e9be5880f 100644
--- a/gs/base/gxistate.h
+++ b/gs/base/gxistate.h
@@ -246,7 +246,8 @@ typedef struct gs_devicen_color_map_s {
float smoothness;\
int renderingintent; /* See gsstate.c */\
gsicc_manager_t *icc_manager; /* ICC color manager, profile */\
- gsicc_link_cache_t *icc_cache; /* ICC linked transforms */\
+ gsicc_link_cache_t *icc_link_cache; /* ICC linked transforms */\
+ gsicc_profile_list_t *icc_profile_cache; /* ICC profiles. */\
CUSTOM_COLOR_PTR /* Pointer to custom color callback struct */\
const gx_color_map_procs *\
(*get_cmap_procs)(const gs_imager_state *, const gx_device *);\
@@ -280,7 +281,7 @@ struct gs_imager_state_s {
lop_default, gx_max_color_value, BLEND_MODE_Compatible,\
{ 1.0 }, { 1.0 }, 0, 0/*false*/, 0, 0, 0, 0, 0/*false*/, 0, 0, 1.0, \
{ fixed_half, fixed_half }, 0/*false*/, 0/*false*/, 0/*false*/, 1.0,\
- 1, 0, 0, INIT_CUSTOM_COLOR_PTR /* 'Custom color' callback pointer */ \
+ 1, 0, 0, 0, INIT_CUSTOM_COLOR_PTR /* 'Custom color' callback pointer */ \
gx_default_get_cmap_procs
/* The imager state structure is public only for subclassing. */
diff --git a/gs/base/lib.mak b/gs/base/lib.mak
index e513f0702..62f00915d 100644
--- a/gs/base/lib.mak
+++ b/gs/base/lib.mak
@@ -348,7 +348,7 @@ gsimage_h=$(GLSRC)gsimage.h $(gsiparam_h)
gsline_h=$(GLSRC)gsline.h $(gslparam_h)
gspath_h=$(GLSRC)gspath.h $(gspenum_h)
gsrop_h=$(GLSRC)gsrop.h $(gsropt_h)
-gstparam_h=$(GLSRC)gstparam.h $(gsccolor_h) $(gsrefct_h)
+gstparam_h=$(GLSRC)gstparam.h $(gsccolor_h) $(gsrefct_h) $(gscspace_h)
gxalpha_h=$(GLSRC)gxalpha.h
gxbcache_h=$(GLSRC)gxbcache.h $(gxbitmap_h)
@@ -2450,7 +2450,7 @@ $(GLOBJ)gxctable.$(OBJ) : $(GLSRC)gxctable.c $(GX)\
# ---------------- ICCBased color ---------------- #
gsicc_=$(GLOBJ)gsiccmanage.$(OBJ) $(GLOBJ)gsicccache.$(OBJ)\
- $(GLOBJ)gsicc_littlecms.$(OBJ)
+ $(GLOBJ)gsicc_littlecms.$(OBJ) $(GLOBJ)gsicc_profilecache.$(OBJ)
sicclib_=$(GLOBJ)gsicc.$(OBJ)
$(GLD)sicclib.dev : $(LIB_MAK) $(ECHOGS_XE) $(sicclib_) $(gsicc_)\
@@ -2468,6 +2468,7 @@ gscms_h=$(std_h) $(stdpre_h) $(gstypes_h) $(gsutil_h) $(stdint_h)
gsicc_littlecms_h=$(GLSRC)gsicc_littlecms.h $(gxcvalue_h) $(gscms_h)
gsiccmanage_h=$(GLSRC)gsiccmanage.h $(gsicc_littlecms_h)
gsicccache_h=$(GLSRC)gsicccache.h $(GX)
+gsicc_profilecache_h=$(GLSRC)gsicc_profilecache.h
$(GLOBJ)gsiccmanage.$(OBJ) : $(GLSRC)gsiccmanage.c $(GX) $(stdpre_h)\
$(gstypes_h) $(gsmemory_h) $(gsstruct_h) $(scommon_h) $(strmio_h)\
@@ -2480,7 +2481,13 @@ $(GLOBJ)gsicccache.$(OBJ) : $(GLSRC)gsicccache.c $(GX) $(stdpre_h)\
$(gxistate_h) $(gscms_h) $(gsiccmanage_h) $(gsicccache_h)\
$(gserrors_h)
$(GLCC) $(GLO_)gsicccache.$(OBJ) $(C_) $(GLSRC)gsicccache.c
-
+
+$(GLOBJ)gsicc_profilecache.$(OBJ) : $(GLSRC)gsicc_profilecache.c $(GX) $(std_h)\
+ $(stdpre_h) $(gstypes_h) $(gsmemory_h) $(gsstruct_h) $(scommon_h)\
+ $(gscms_h) $(gsicc_profilecache_h)\
+ $(gserrors_h)
+ $(GLCC) $(GLO_)gsicc_profilecache.$(OBJ) $(C_) $(GLSRC)gsicc_profilecache.c
+
$(GLOBJ)gsicc_littlecms.$(OBJ) : $(GLSRC)gsicc_littlecms.c\
$(gsicc_littlecms_h)
$(GLLCMSCC) $(GLO_)gsicc_littlecms.$(OBJ) $(C_) $(GLSRC)gsicc_littlecms.c