[gs-commits] rev 10947 - branches/icc_work/base
mvrhel at ghostscript.com
mvrhel at ghostscript.com
Fri Mar 19 18:59:38 UTC 2010
Author: mvrhel
Date: 2010-03-19 18:59:38 +0000 (Fri, 19 Mar 2010)
New Revision: 10947
Modified:
branches/icc_work/base/gxicolor.c
Log:
Return of decode methods into gxicolor.c These do not occur that often so should have minimal impact on performance.
Modified: branches/icc_work/base/gxicolor.c
===================================================================
--- branches/icc_work/base/gxicolor.c 2010-03-19 18:30:04 UTC (rev 10946)
+++ branches/icc_work/base/gxicolor.c 2010-03-19 18:59:38 UTC (rev 10947)
@@ -132,6 +132,41 @@
return(false);
}
+static void
+decode_row(gx_image_enum *penum, byte *psrc, int spp, byte *pdes,
+ byte *bufend)
+{
+ byte *curr_pos = pdes;
+ int k;
+ float temp;
+
+ while ( curr_pos < bufend ) {
+ for ( k = 0; k < spp; k ++ ) {
+ switch ( penum->map[k].decoding ) {
+ case sd_none:
+ *curr_pos = *psrc;
+ break;
+ case sd_lookup:
+ temp = penum->map[k].decode_lookup[(*psrc) >> 4]*255.0;
+ if (temp > 255) temp = 255;
+ if (temp < 0 ) temp = 0;
+ *curr_pos = (unsigned char) temp;
+ break;
+ case sd_compute:
+ temp = penum->map[k].decode_base +
+ (*psrc) * penum->map[k].decode_factor;
+ if (temp > 255) temp = 255;
+ if (temp < 0 ) temp = 0;
+ *curr_pos = (unsigned char) temp;
+ default:
+ break;
+ }
+ curr_pos++;
+ psrc++;
+ }
+ }
+}
+
/* Render a color image with 8 or fewer bits per sample using ICC profile. */
static int
image_render_color_icc(gx_image_enum *penum_orig, const byte *buffer, int data_x,
@@ -167,7 +202,7 @@
gsicc_link_t *icc_link;
gsicc_bufferdesc_t input_buff_desc;
gsicc_bufferdesc_t output_buff_desc;
- unsigned char *psrc_cm, *psrc_cm_start;
+ unsigned char *psrc_cm, *psrc_cm_start, *psrc_decode;
int k;
gx_color_value conc[GX_DEVICE_COLOR_MAX_COMPONENTS];
int spp_cm, num_pixels;
@@ -175,7 +210,16 @@
bool must_halftone = gx_device_must_halftone(dev);
bool has_transfer = gx_has_transfer(pis,
pis->icc_manager->device_profile->num_comps);
-
+ int src_num_comp = cs_num_components(penum->pcs);
+ bool need_decode = false;
+
+ /* Check if we need to do any decoding. If yes, then that will slow us down */
+ for (k = 0; k < src_num_comp; k++) {
+ if ( penum->map[k].decoding != sd_none ) {
+ need_decode = true;
+ break;
+ }
+ }
/* Needed for device N */
memset(&(conc[0]), 0, sizeof(gx_color_value[GX_DEVICE_COLOR_MAX_COMPONENTS]));
if (gs_color_space_is_PSCIE(penum->pcs) && penum->pcs->icc_equivalent != NULL) {
@@ -199,34 +243,49 @@
if (icc_link == NULL) {
return gs_rethrow(-1, "ICC Link not created during image render color");
}
- /* If the link is the identity, then we don't need to do any color conversions */
- if (icc_link->is_identity) {
+ /* If the link is the identity, then we don't need to do any color
+ conversions except for potentially a decode. */
+ if (icc_link->is_identity && !need_decode) {
+ /* Fastest case. No decode or CM needed */
psrc_cm = (unsigned char *) psrc;
spp_cm = spp;
bufend = psrc_cm + w;
psrc_cm_start = NULL;
} else {
- /* Set up the buffer descriptors. */
spp_cm = pis->icc_manager->device_profile->num_comps;
- num_pixels = w/spp;
- gsicc_init_buffer(&input_buff_desc, spp, 1,
- false, false, false, 0, w,
- 1, num_pixels);
- gsicc_init_buffer(&output_buff_desc, spp_cm, 1,
- false, false, false, 0, num_pixels * spp_cm,
- 1, num_pixels);
- /* For now, just blast it all through the link. If we had a significant reduction
- we will want to repack the data first and then do this. That will be
- an optimization shortly. Also we are going to have to do something here
- with respect to the decode. If sdnone is the case, then we are fine but the
- others will need to be considered. Also, for now just allocate a new output
- buffer. We can reuse the old one if the number of channels in the output is
- less than or equal to the new one. We will do that soon. */
psrc_cm = gs_alloc_bytes(pis->memory, w * spp_cm/spp, "image_render_color_icc");
psrc_cm_start = psrc_cm;
bufend = psrc_cm + w * spp_cm/spp;
- gscms_transform_color_buffer(icc_link, &input_buff_desc, &output_buff_desc,
- (void*) psrc, (void*) psrc_cm);
+ if (icc_link->is_identity) {
+ /* decode only. no CM. This is slow but does not happen that often */
+ decode_row(penum, psrc, spp, psrc_cm, bufend);
+ } else {
+ /* Set up the buffer descriptors. */
+ num_pixels = w/spp;
+ gsicc_init_buffer(&input_buff_desc, spp, 1,
+ false, false, false, 0, w,
+ 1, num_pixels);
+ gsicc_init_buffer(&output_buff_desc, spp_cm, 1,
+ false, false, false, 0, num_pixels * spp_cm,
+ 1, num_pixels);
+ /* For now, just blast it all through the link. If we had a significant reduction
+ we will want to repack the data first and then do this. That will be
+ an optimization shortly. For now just allocate a new output
+ buffer. We can reuse the old one if the number of channels in the output is
+ less than or equal to the new one. */
+ if (need_decode) {
+ /* Need decode and CM. This is slow but does not happen that often */
+ psrc_decode = gs_alloc_bytes(pis->memory, w, "image_render_color_icc");
+ decode_row(penum, psrc, spp, psrc_decode, psrc_decode+w);
+ gscms_transform_color_buffer(icc_link, &input_buff_desc, &output_buff_desc,
+ (void*) psrc_decode, (void*) psrc_cm);
+ gs_free_object(pis->memory, (byte *)psrc_decode, "image_render_color_icc");
+ } else {
+ /* CM only. No decode */
+ gscms_transform_color_buffer(icc_link, &input_buff_desc, &output_buff_desc,
+ (void*) psrc, (void*) psrc_cm);
+ }
+ }
}
/* Release the link */
gsicc_release_link(icc_link);
More information about the gs-commits
mailing list