diff options
author | Michael Vrhel <michael.vrhel@artifex.com> | 2012-04-11 15:07:43 -0700 |
---|---|---|
committer | Michael Vrhel <michael.vrhel@artifex.com> | 2012-05-10 11:12:10 -0700 |
commit | 79925e26467289515d4cf499d2c3a2d3b1cdcaa4 (patch) | |
tree | fbbd18e98e2b31ff4fdf31187a53b372e517f189 /gs/base | |
parent | c6d74690be87eb37ca5b4590ed6b44673e4125c7 (diff) |
Delay of obtaining handles from CMM for default profiles
Obtaining the profiles handles for all the default profiles in
the ICC manager eats up a tiny amount of time on startup. For
some customers that start and stop gs over and over instead of
running in server mode, this startup time is an issue. This
fix performs the initialization in a lazy manner, obtaining the
profile handle only when finally needed.
This commit also fixed some issues with images that are in the
LAB color space.
Diffstat (limited to 'gs/base')
-rw-r--r-- | gs/base/gdevp14.c | 8 | ||||
-rw-r--r-- | gs/base/gscdevn.c | 3 | ||||
-rw-r--r-- | gs/base/gscsepr.c | 3 | ||||
-rw-r--r-- | gs/base/gsicc.c | 76 | ||||
-rw-r--r-- | gs/base/gsicc.h | 1 | ||||
-rw-r--r-- | gs/base/gsicc_cache.c | 8 | ||||
-rw-r--r-- | gs/base/gsicc_manage.c | 126 | ||||
-rw-r--r-- | gs/base/gsicc_manage.h | 1 | ||||
-rw-r--r-- | gs/base/gstrans.c | 3 | ||||
-rw-r--r-- | gs/base/gxclimag.c | 8 | ||||
-rw-r--r-- | gs/base/gxcmap.c | 2 | ||||
-rw-r--r-- | gs/base/gxicolor.c | 27 | ||||
-rw-r--r-- | gs/base/lib.mak | 2 |
13 files changed, 199 insertions, 69 deletions
diff --git a/gs/base/gdevp14.c b/gs/base/gdevp14.c index 83e634e05..5cbb06dcf 100644 --- a/gs/base/gdevp14.c +++ b/gs/base/gdevp14.c @@ -4945,7 +4945,7 @@ gs_pdf14_device_push(gs_memory_t *mem, gs_imager_state * pis, proper blending. During put_image we will convert from RGB to CIELAB. Need to check that we have a default profile, which will not be the case if we are coming from the clist reader */ - if (icc_profile->data_cs == gsCIELAB + if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab) && pis->icc_manager->default_rgb != NULL) { p14dev->icc_struct->device_profile[0] = pis->icc_manager->default_rgb; @@ -5085,7 +5085,7 @@ c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize, to CIELAB at the end. To do this, we need to store the default RGB profile in the clist so that we can grab it later on during the clist read back and put image command */ - if (icc_profile->data_cs == gsCIELAB) { + if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) { /* Get the default RGB profile. Set the device hash code so that we can extract it during the put_image operation. */ cdev->trans_dev_icc_hash = pparams->iccprofile->hashcode; @@ -6022,7 +6022,7 @@ pdf14_create_clist_device(gs_memory_t *mem, gs_imager_state * pis, /* If the target profile was CIELAB, then overide with default RGB for proper blending. During put_image we will convert from RGB to CIELAB */ - if (target_profile->data_cs == gsCIELAB) { + if (target_profile->data_cs == gsCIELAB || target_profile->islab) { rc_assign(pdev->icc_struct->device_profile[0], pis->icc_manager->default_rgb, "pdf14_create_clist_device"); } @@ -7285,7 +7285,7 @@ c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev, device. This will occur if our source profile for our device happens to be something like CIELAB. Then we will blend in RGB (unless a trans group is specified) */ - if (cl_icc_profile->data_cs == gsCIELAB) { + if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) { cl_icc_profile = gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash); /* Keep a pointer to the clist device */ diff --git a/gs/base/gscdevn.c b/gs/base/gscdevn.c index 0d01108b1..d095d2383 100644 --- a/gs/base/gscdevn.c +++ b/gs/base/gscdevn.c @@ -441,7 +441,8 @@ gx_concretize_DeviceN(const gs_client_color * pc, const gs_color_space * pcs, /* Use the ICC equivalent color space */ pacs = pacs->icc_equivalent; } - if (pacs->cmm_icc_profile_data->data_cs == gsCIELAB) { + if (pacs->cmm_icc_profile_data->data_cs == gsCIELAB || + pacs->cmm_icc_profile_data->islab) { /* Get the data in a form that is concrete for the CMM */ cc.paint.values[0] /= 100.0; cc.paint.values[1] = (cc.paint.values[1]+128)/255.0; diff --git a/gs/base/gscsepr.c b/gs/base/gscsepr.c index 021109758..6c117da22 100644 --- a/gs/base/gscsepr.c +++ b/gs/base/gscsepr.c @@ -361,7 +361,8 @@ gx_concretize_Separation(const gs_client_color *pc, const gs_color_space *pcs, /* Use the ICC equivalent color space */ pacs = pacs->icc_equivalent; } - if (pacs->cmm_icc_profile_data->data_cs == gsCIELAB) { + if (pacs->cmm_icc_profile_data->data_cs == gsCIELAB || + pacs->cmm_icc_profile_data->islab) { /* Get the data in a form that is concrete for the CMM */ cc.paint.values[0] /= 100.0; cc.paint.values[1] = (cc.paint.values[1]+128)/255.0; diff --git a/gs/base/gsicc.c b/gs/base/gsicc.c index 6b7ce867e..d1fc60467 100644 --- a/gs/base/gsicc.c +++ b/gs/base/gsicc.c @@ -51,6 +51,7 @@ static cs_proc_final(gx_final_ICC); static cs_proc_serialize(gx_serialize_ICC); static cs_proc_is_linear(gx_cspace_is_linear_ICC); static cs_proc_set_overprint(gx_set_overprint_ICC); +cs_proc_remap_color(gx_remap_ICC_imagelab); const gs_color_space_type gs_color_space_type_ICC = { gs_color_space_index_ICC, /* index */ @@ -336,7 +337,8 @@ gx_remap_ICC(const gs_client_color * pcc, const gs_color_space * pcs, memset(psrc_cm,0,sizeof(unsigned short)*GS_CLIENT_COLOR_MAX_COMPONENTS); /* This needs to be optimized */ - if (pcs->cmm_icc_profile_data->data_cs == gsCIELAB) { + if (pcs->cmm_icc_profile_data->data_cs == gsCIELAB || + pcs->cmm_icc_profile_data->islab) { psrc[0] = (unsigned short) (pcc->paint.values[0]*65535.0/100.0); psrc[1] = (unsigned short) ((pcc->paint.values[1]+128)/255.0*65535.0); psrc[2] = (unsigned short) ((pcc->paint.values[2]+128)/255.0*65535.0); @@ -390,9 +392,75 @@ gx_remap_ICC(const gs_client_color * pcc, const gs_color_space * pcs, return 0; } - /* - * Convert an ICCBased color space to a concrete color space. - */ +/* + * 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_imager_state * pis, 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); + num_des_comps = gsicc_get_device_profile_comps(dev_profile); + rendering_params.black_point_comp = BP_ON; + rendering_params.graphics_type_tag = dev->graphics_type_tag; + /* Need to figure out which one rules here on rendering intent. The + source of the device */ + rendering_params.rendering_intent = pis->renderingintent; + + /* 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(pis, dev, pcs, NULL, &rendering_params, pis->memory); + if (icc_link == NULL) { + return gs_rethrow(-1, "Could not create ICC link: Check profiles"); + } + 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, pis, 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; +} + +/* Convert an ICCBased color space to a concrete color space. */ + static int gx_concretize_ICC( const gs_client_color * pcc, diff --git a/gs/base/gsicc.h b/gs/base/gsicc.h index c8f75ff74..c83851d20 100644 --- a/gs/base/gsicc.h +++ b/gs/base/gsicc.h @@ -29,5 +29,6 @@ extern int gs_cspace_build_ICC( gs_color_space ** ppcspace, gs_memory_t * pmem ); extern const gs_color_space_type gs_color_space_type_ICC; +extern cs_proc_remap_color(gx_remap_ICC_imagelab); #endif /* gsicc_INCLUDED */ diff --git a/gs/base/gsicc_cache.c b/gs/base/gsicc_cache.c index d06aa868b..f734e9679 100644 --- a/gs/base/gsicc_cache.c +++ b/gs/base/gsicc_cache.c @@ -658,6 +658,11 @@ gsicc_get_link_profile(const gs_imager_state *pis, gx_device *dev, gsicc_get_profile_handle_buffer(gs_input_profile->buffer, gs_input_profile->buffer_size); gs_input_profile->profile_handle = cms_input_profile; + /* This *must* be a default profile that was not set up at start-up/ + However it could be one from the icc creator code which does not + do an initialization at the time of creation from CalRGB etc. */ + code = gsicc_initialize_default_profile(gs_input_profile); + if (code < 0) return (NULL); } else { /* See if we have a clist device pointer. */ if ( gs_input_profile->dev != NULL ) { @@ -686,6 +691,9 @@ gsicc_get_link_profile(const gs_imager_state *pis, gx_device *dev, gsicc_get_profile_handle_buffer(gs_output_profile->buffer, gs_output_profile->buffer_size); gs_output_profile->profile_handle = cms_output_profile; + /* This *must* be a default profile that was not set up at start-up */ + code = gsicc_initialize_default_profile(gs_output_profile); + if (code < 0) return (NULL); } else { /* See if we have a clist device pointer. */ if ( gs_output_profile->dev != NULL ) { diff --git a/gs/base/gsicc_manage.c b/gs/base/gsicc_manage.c index 48e1f8bd6..62bbf20d2 100644 --- a/gs/base/gsicc_manage.c +++ b/gs/base/gsicc_manage.c @@ -610,13 +610,13 @@ int gsicc_set_profile(gsicc_manager_t *icc_manager, const char* pname, int namelen, gsicc_profile_t defaulttype) { - cmm_profile_t *icc_profile; cmm_profile_t **manager_default_profile = NULL; /* quite compiler */ stream *str; gs_memory_t *mem_gc = icc_manager->memory; int code; int k; + int num_comps = 0; gsicc_colorbuffer_t default_space; /* Used to verify that we have the correct type */ /* We need to check for the smask swapped profile condition. If we are in @@ -633,23 +633,30 @@ gsicc_set_profile(gsicc_manager_t *icc_manager, const char* pname, int namelen, case DEFAULT_GRAY: manager_default_profile = &(icc_manager->default_gray); default_space = gsGRAY; + num_comps = 1; break; case DEFAULT_RGB: manager_default_profile = &(icc_manager->default_rgb); default_space = gsRGB; + num_comps = 3; break; case DEFAULT_CMYK: manager_default_profile = &(icc_manager->default_cmyk); default_space = gsCMYK; + num_comps = 4; break; case NAMED_TYPE: manager_default_profile = &(icc_manager->device_named); + default_space = gsNAMED; break; case LAB_TYPE: manager_default_profile = &(icc_manager->lab_profile); + num_comps = 3; + default_space = gsCIELAB; break; case DEVICEN_TYPE: code = gsicc_new_devicen(icc_manager); + default_space = gsNCHANNEL; if (code == 0) { manager_default_profile = &(icc_manager->device_n->final->iccprofile); @@ -715,45 +722,84 @@ gsicc_set_profile(gsicc_manager_t *icc_manager, const char* pname, int namelen, code = gsicc_load_namedcolor_buffer(icc_profile, str, mem_gc); if (code < 0) gs_rethrow1(-1, "problems with profile %s",pname); *manager_default_profile = icc_profile; - return(0); /* Done now, since this is not a standard ICC profile */ + return 0; /* Done now, since this is not a standard ICC profile */ } code = sfclose(str); if (icc_profile == NULL) { return gs_rethrow1(-1, "problems with profile %s",pname); } - *manager_default_profile = icc_profile; + *manager_default_profile = icc_profile; + icc_profile->default_match = defaulttype; + if (defaulttype == LAB_TYPE) + icc_profile->islab = true; + if ( defaulttype == DEVICEN_TYPE ) { + /* Lets get the name information out of the profile. + The names are contained in the icSigNamedColor2Tag + item. The table is in the A2B0Tag item. + The names are in the order such that the fastest + index in the table is the first name */ + gsicc_get_devicen_names(icc_profile, icc_manager->memory); + } + /* Delay the loading of the handle buffer until we need the profile. + But set some basic stuff that we need */ + icc_profile->num_comps = num_comps; + icc_profile->num_comps_out = 3; + gscms_set_icc_range(&icc_profile); + icc_profile->data_cs = default_space; + return 0; + } + return -1; +} - /* Get the profile handle */ - icc_profile->profile_handle = - gsicc_get_profile_handle_buffer(icc_profile->buffer, - icc_profile->buffer_size); +/* This is used ONLY for delayed initialization of the "default" ICC profiles + that are in the ICC manager. This way we avoid getting these profile handles + until we actually need them. Note that defaulttype is preset. These are + the *only* profiles that are delayed in this manner. All embedded profiles + and internally generated profiles have their handles found immediately */ +int +gsicc_initialize_default_profile(cmm_profile_t *icc_profile) +{ + gsicc_profile_t defaulttype = icc_profile->default_match; + gsicc_colorbuffer_t default_space = gsUNDEFINED; + int num_comps, num_comps_out; + + /* Get the profile handle if it is not already set */ + if (icc_profile->profile_handle != NULL) { + icc_profile->profile_handle = + gsicc_get_profile_handle_buffer(icc_profile->buffer, + icc_profile->buffer_size); if (icc_profile->profile_handle == NULL) { - return gs_rethrow1(-1, "allocation of profile %s handle failed", pname); + return gs_rethrow1(-1, "allocation of profile %s handle failed", + icc_profile->name); } - /* Compute the hash code of the profile. Everything in the ICC manager will have - it's hash code precomputed */ + } + if (icc_profile->buffer != NULL && icc_profile->hash_is_valid == false) { + /* Compute the hash code of the profile. */ gsicc_get_icc_buff_hash(icc_profile->buffer, &(icc_profile->hashcode), icc_profile->buffer_size); icc_profile->hash_is_valid = true; - icc_profile->default_match = defaulttype; - icc_profile->num_comps = - gscms_get_input_channel_count(icc_profile->profile_handle); - icc_profile->num_comps_out = - gscms_get_output_channel_count(icc_profile->profile_handle); - icc_profile->data_cs = - gscms_get_profile_data_space(icc_profile->profile_handle); - - if_debug0(gs_debug_flag_icc,"[icc] Setting ICC profile in Manager\n"); -#ifdef DEBUG /* Don't want this switch in here if we are not in debug mode */ + } + num_comps = icc_profile->num_comps; + icc_profile->num_comps = + gscms_get_input_channel_count(icc_profile->profile_handle); + num_comps_out = icc_profile->num_comps_out; + icc_profile->num_comps_out = + gscms_get_output_channel_count(icc_profile->profile_handle); + icc_profile->data_cs = + gscms_get_profile_data_space(icc_profile->profile_handle); + if_debug0(gs_debug_flag_icc,"[icc] Setting ICC profile in Manager\n"); switch(defaulttype) { case DEFAULT_GRAY: if_debug0(gs_debug_flag_icc,"[icc] Default Gray\n"); + default_space = gsGRAY; break; case DEFAULT_RGB: - if_debug0(gs_debug_flag_icc,"[icc] Default RGB\n"); + if_debug0(gs_debug_flag_icc,"[icc] Default RGB\n"); + default_space = gsRGB; break; case DEFAULT_CMYK: - if_debug0(gs_debug_flag_icc,"[icc] Default CMYK\n"); + if_debug0(gs_debug_flag_icc,"[icc] Default CMYK\n"); + default_space = gsCMYK; break; case NAMED_TYPE: if_debug0(gs_debug_flag_icc,"[icc] Named Color\n"); @@ -769,34 +815,18 @@ gsicc_set_profile(gsicc_manager_t *icc_manager, const char* pname, int namelen, return(0); break; } -#endif - if_debug1(gs_debug_flag_icc,"[icc] name = %s\n", icc_profile->name); - if_debug1(gs_debug_flag_icc,"[icc] num_comps = %d\n", icc_profile->num_comps); - /* Check that we have the proper color space for the ICC - profiles that can be externally set */ - if (default_space != gsUNDEFINED) { - if (icc_profile->data_cs != default_space) { - return gs_rethrow(-1, "A default profile has an incorrect color space"); - } - } - /* Initialize the range to default values */ - for ( k = 0; k < icc_profile->num_comps; k++) { - icc_profile->Range.ranges[k].rmin = 0.0; - icc_profile->Range.ranges[k].rmax = 1.0; - } - if (defaulttype == LAB_TYPE) - icc_profile->islab = true; - if ( defaulttype == DEVICEN_TYPE ) { - /* Lets get the name information out of the profile. - The names are contained in the icSigNamedColor2Tag - item. The table is in the A2B0Tag item. - The names are in the order such that the fastest - index in the table is the first name */ - gsicc_get_devicen_names(icc_profile, icc_manager->memory); + if_debug1(gs_debug_flag_icc,"[icc] name = %s\n", icc_profile->name); + if_debug1(gs_debug_flag_icc,"[icc] num_comps = %d\n", icc_profile->num_comps); + /* Check that we have the proper color space for the ICC + profiles that can be externally set */ + if (default_space != gsUNDEFINED || + num_comps != icc_profile->num_comps || + num_comps_out != icc_profile->num_comps_out) { + if (icc_profile->data_cs != default_space) { + return gs_rethrow(-1, "A default profile has an incorrect color space"); } - return(0); } - return(-1); + return 0; } /* This is used to get the profile handle given a file name */ diff --git a/gs/base/gsicc_manage.h b/gs/base/gsicc_manage.h index 679ac5d7a..ec55a1f9b 100644 --- a/gs/base/gsicc_manage.h +++ b/gs/base/gsicc_manage.h @@ -88,6 +88,7 @@ int gsicc_set_srcgtag_struct(gsicc_manager_t *icc_manager, const char* pname, cmm_profile_t* gsicc_get_profile_handle_file(const char* pname, int namelen, gs_memory_t *mem); void gsicc_init_profile_info(cmm_profile_t *profile); +int gsicc_initialize_default_profile(cmm_profile_t *icc_profile); gsicc_manager_t* gsicc_manager_new(gs_memory_t *memory); cmm_profile_t* gsicc_profile_new(stream *s, gs_memory_t *memory, const char* pname, int namelen); diff --git a/gs/base/gstrans.c b/gs/base/gstrans.c index 6c96b06d1..e15b82fb5 100644 --- a/gs/base/gstrans.c +++ b/gs/base/gstrans.c @@ -797,7 +797,8 @@ gs_push_pdf14trans_device(gs_state * pgs, bool is_pattern) whose profile is CIELAB then we will need to make sure that we do our blending in RGB and convert to CIELAB when we do the put_image command */ - if (icc_profile->data_cs == gsCIELAB) { + if (icc_profile->data_cs == gsCIELAB || + icc_profile->islab) { params.iccprofile = pgs->icc_manager->default_rgb; } /* Note: Other parameters not used */ diff --git a/gs/base/gxclimag.c b/gs/base/gxclimag.c index 9d307ca42..ed9ab4bbe 100644 --- a/gs/base/gxclimag.c +++ b/gs/base/gxclimag.c @@ -36,6 +36,7 @@ #include "gxdhtserial.h" #include "gsptype1.h" #include "gsicc_manage.h" +#include "gsicc_cache.h" extern_gx_image_type_table(); @@ -535,6 +536,13 @@ clist_begin_typed_image(gx_device * dev, } if (renderingintent != pis_nonconst->renderingintent) intent_changed = true; + if (!(src_profile->hash_is_valid)) { + int64_t hash; + gsicc_get_icc_buff_hash(src_profile->buffer, &hash, + src_profile->buffer_size); + src_profile->hashcode = hash; + src_profile->hash_is_valid = true; + } pie->color_space.icc_info.icc_hash = src_profile->hashcode; pie->color_space.icc_info.icc_num_components = src_profile->num_comps; diff --git a/gs/base/gxcmap.c b/gs/base/gxcmap.c index b32c5c874..182c86e6b 100644 --- a/gs/base/gxcmap.c +++ b/gs/base/gxcmap.c @@ -1208,7 +1208,7 @@ cmap_separation_direct(frac all, gx_device_color * pdc, const gs_imager_state * on how addivite devices should behave with the ALL option but it is clear from testing the AR 10 does simply do the RGB = 1 - INK type of mapping */ - if (des_profile->data_cs == gsCIELAB) { + if (des_profile->data_cs == gsCIELAB || des_profile->islab) { use_rgb2dev_icc = true; } } diff --git a/gs/base/gxicolor.c b/gs/base/gxicolor.c index 358a6dd8f..c958c56be 100644 --- a/gs/base/gxicolor.c +++ b/gs/base/gxicolor.c @@ -288,7 +288,6 @@ image_color_icc_prep(gx_image_enum *penum_orig, const byte *psrc, uint w, { const gx_image_enum *const penum = penum_orig; /* const within proc */ const gs_imager_state *pis = penum->pis; - const gs_color_space *pcs; bool need_decode = penum->icc_setup.need_decode; gsicc_bufferdesc_t input_buff_desc; gsicc_bufferdesc_t output_buff_desc; @@ -300,15 +299,11 @@ image_color_icc_prep(gx_image_enum *penum_orig, const byte *psrc, uint w, 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); if (penum->icc_link == NULL) { return gs_rethrow(-1, "ICC Link not created during image render color"); } - if (gs_color_space_is_PSCIE(penum->pcs) && penum->pcs->icc_equivalent != NULL) { - pcs = penum->pcs->icc_equivalent; - } else { - pcs = penum->pcs; - } /* If the link is the identity, then we don't need to do any color conversions except for potentially a decode. Planar out is a special case. For now we let the CMM do the reorg into planar. We will want @@ -1015,9 +1010,20 @@ image_render_color_DeviceN(gx_image_enum *penum_orig, const byte *buffer, int da int i; bits32 mask = penum->mask_color.mask; bits32 test = penum->mask_color.test; + bool lab_case = false; if (h == 0) return 0; + + /* Decide on which remap proc to use. If the source colors are LAB + then use the mapping that does not rescale the source colors */ + if (gs_color_space_is_ICC(pcs) && pcs->cmm_icc_profile_data != NULL && + pcs->cmm_icc_profile_data->islab) { + remap_color = gx_remap_ICC_imagelab; + lab_case = true; + } else { + remap_color = pcs->type->remap_color; + } pdevc = &devc1; pdevc_next = &devc2; /* In case these are devn colors */ @@ -1068,8 +1074,13 @@ image_render_color_DeviceN(gx_image_enum *penum_orig, const byte *buffer, int da color_set_null(pdevc_next); goto mapped; } - for (i = 0; i < spp; ++i) - decode_sample(next.v[i], cc, i); + /* Data is already properly set up for ICC use of LAB */ + if (lab_case) + for (i = 0; i < spp; ++i) + cc.paint.values[i] = (next.v[i]) * (1.0f / 255.0f); + else + for (i = 0; i < spp; ++i) + decode_sample(next.v[i], cc, i); #ifdef DEBUG if (gs_debug_c('B')) { dprintf2("[B]cc[0..%d]=%g", spp - 1, diff --git a/gs/base/lib.mak b/gs/base/lib.mak index b9df6e8eb..abb7b853d 100644 --- a/gs/base/lib.mak +++ b/gs/base/lib.mak @@ -1971,7 +1971,7 @@ $(GLOBJ)gxclimag.$(OBJ) : $(GLSRC)gxclimag.c $(AK) $(gx_h)\ $(gxarith_h) $(gxcldev_h) $(gxclpath_h) $(gxcspace_h)\ $(gxdevice_h) $(gxdevmem_h) $(gxfmap_h) $(gxiparam_h) $(gxpath_h)\ $(sisparam_h) $(stream_h) $(strimpl_h) $(gxcomp_h) $(gsserial_h)\ - $(gxdhtserial_h) $(gsptype1_h) $(gsicc_manage_h) $(MAKEDIRS) + $(gxdhtserial_h) $(gsptype1_h) $(gsicc_manage_h) $(gsicc_cache_h) $(MAKEDIRS) $(GLCC) $(GLO_)gxclimag.$(OBJ) $(C_) $(GLSRC)gxclimag.c $(GLOBJ)gxclpath.$(OBJ) : $(GLSRC)gxclpath.c $(AK) $(gx_h)\ |