[gs-commits] rev 10943 - branches/icc_work/base

mvrhel at ghostscript.com mvrhel at ghostscript.com
Thu Mar 18 20:34:26 UTC 2010


Author: mvrhel
Date: 2010-03-18 20:34:24 +0000 (Thu, 18 Mar 2010)
New Revision: 10943

Modified:
   branches/icc_work/base/gdevp14.c
   branches/icc_work/base/gsicc_littlecms.c
   branches/icc_work/base/gstrans.c
   branches/icc_work/base/gxblend.c
   branches/icc_work/base/gxblend.h
   branches/icc_work/base/lib.mak
Log:
Fixes for issues with soft mask in icc branch.  This approach makes the pdf14 device use a gray color space when the soft mask is pushed.  Internal groups to the mask can still be blended in other spaces, but with this approach we end up avoiding a final conversion to the gray mask at the end.  Comparison with AR appears to be very close. 

Modified: branches/icc_work/base/gdevp14.c
===================================================================
--- branches/icc_work/base/gdevp14.c	2010-03-18 20:30:00 UTC (rev 10942)
+++ branches/icc_work/base/gdevp14.c	2010-03-18 20:34:24 UTC (rev 10943)
@@ -1022,11 +1022,24 @@
 }
 
 static	int
-pdf14_pop_transparency_mask(pdf14_ctx *ctx)
+pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_imager_state *pis)
 {
     pdf14_buf *tos = ctx->stack;
     byte *new_data_buf;
+    int icc_match;
+    cmm_profile_t *des_profile = tos->parent_color_info_procs->icc_profile; /* If set, this should be a gray profile */
+    cmm_profile_t *src_profile = pis->icc_manager->device_profile;    
+    gsicc_rendering_param_t rendering_params;
+    gsicc_link_t *icc_link;
 
+    /* icc_match == -1 means old non-icc code.
+       icc_match == 0 means use icc code 
+       icc_match == 1 mean no conversion needed */
+    if ( des_profile != NULL && src_profile != NULL ) {
+        icc_match = (des_profile->hashcode ==  src_profile->hashcode);
+    } else {
+        icc_match = -1;
+    }
     if_debug1('v', "[v]pdf14_pop_transparency_mask, idle=%d\n", tos->idle);
     ctx->stack = tos->saved;
     tos->saved = NULL;  /* To avoid issues with GC */
@@ -1060,6 +1073,8 @@
             ctx->maskbuf->rc_mask->mask_buf = tos;
         }
     } else {
+        /* If we are already in the source space then there is no reason 
+           to do the transformation */
         /* Lets get this to a monochrome buffer and map it to a luminance only value */
         /* This will reduce our memory.  We won't reuse the existing one, due */
         /* Due to the fact that on certain systems we may have issues recovering */
@@ -1072,10 +1087,36 @@
            we won't be filling everything during the remap if it had not been 
            written into by the PDF14 fill rect */
         memset(new_data_buf, 0, tos->planestride);
-        Smask_Luminosity_Mapping(tos->rect.q.y - tos->rect.p.y ,
-            tos->rect.q.x - tos->rect.p.x,tos->n_chan, 
-            tos->rowstride, tos->planestride, new_data_buf, tos->data, ctx->additive,
-            tos->SMask_is_CIE, tos->SMask_SubType); 
+        if ( icc_match == 1 || tos->n_chan == 2) {
+            /* There is no need to convert.  Data is already gray scale.
+               We just need to copy the gray plane */
+            smask_copy(tos->rect.q.y - tos->rect.p.y,
+                       tos->rect.q.x - tos->rect.p.x, 
+                       tos->rowstride, tos->data, new_data_buf);
+        } else {
+            if ( icc_match == -1 ) {
+                /* The slow old fashioned way */
+                smask_luminosity_mapping(tos->rect.q.y - tos->rect.p.y ,
+                    tos->rect.q.x - tos->rect.p.x,tos->n_chan, 
+                    tos->rowstride, tos->planestride, 
+                    tos->data,  new_data_buf, ctx->additive,
+                    tos->SMask_is_CIE, tos->SMask_SubType); 
+            } else {
+                /* ICC case where we use the CMM */
+                /* Request the ICC link for the transform that we will need to use */
+                rendering_params.black_point_comp = BP_OFF;
+                rendering_params.object_type = GS_IMAGE_TAG;
+                rendering_params.rendering_intent = gsPERCEPTUAL;
+                icc_link = gsicc_get_link_profile(pis, des_profile, 
+                    src_profile, &rendering_params, pis->memory, false);
+                smask_icc(tos->rect.q.y - tos->rect.p.y ,
+                                    tos->rect.q.x - tos->rect.p.x,tos->n_chan, 
+                                    tos->rowstride, tos->planestride, 
+                                    tos->data, new_data_buf, icc_link);
+                /* Release the link */
+                gsicc_release_link(icc_link);
+            }
+        }
          /* Free the old object, NULL test was above */
           gs_free_object(ctx->memory, tos->data, "pdf14_buf_free");
              tos->data = new_data_buf;
@@ -3084,7 +3125,7 @@
     int ok;
 
     if_debug0('v', "pdf14_end_transparency_mask\n");
-    ok = pdf14_pop_transparency_mask(pdev->ctx);
+    ok = pdf14_pop_transparency_mask(pdev->ctx, pis);
     /* May need to reset some color stuff related
      * to a mismatch between the Smask color space
      * and the Smask blending space */

Modified: branches/icc_work/base/gsicc_littlecms.c
===================================================================
--- branches/icc_work/base/gsicc_littlecms.c	2010-03-18 20:30:00 UTC (rev 10942)
+++ branches/icc_work/base/gsicc_littlecms.c	2010-03-18 20:34:24 UTC (rev 10943)
@@ -267,8 +267,10 @@
     des_data_type = des_data_type | ENDIAN16_SH(1);
 #endif
 /* Create the link */
-    return(cmsCreateTransform(lcms_srchandle, src_data_type, lcms_deshandle, des_data_type, 
-        rendering_params->rendering_intent, (cmsFLAGS_BLACKPOINTCOMPENSATION | cmsFLAGS_HIGHRESPRECALC) /*cmsFLAGS_LOWRESPRECALC*/));	
+    return(cmsCreateTransform(lcms_srchandle, src_data_type, lcms_deshandle, 
+                        des_data_type, rendering_params->rendering_intent, 
+               (cmsFLAGS_BLACKPOINTCOMPENSATION | cmsFLAGS_HIGHRESPRECALC)));
+    /* cmsFLAGS_HIGHRESPRECALC)  cmsFLAGS_NOTPRECALC  cmsFLAGS_LOWRESPRECALC*/	
 }
 
 /* Get the link from the CMS, but include proofing. 

Modified: branches/icc_work/base/gstrans.c
===================================================================
--- branches/icc_work/base/gstrans.c	2010-03-18 20:30:00 UTC (rev 10942)
+++ branches/icc_work/base/gstrans.c	2010-03-18 20:34:24 UTC (rev 10943)
@@ -521,13 +521,12 @@
     gs_pdf14trans_params_t params = { 0 };
     const int l = sizeof(params.Background[0]) * ptmp->Background_components;
     int i;
-    const gs_color_space *blend_color_space;
+    gs_color_space *blend_color_space;
     int num_components;
 
     params.pdf14_op = PDF14_BEGIN_TRANS_MASK;
     params.bbox = *pbbox;
     params.subtype = ptmp->subtype;
-   /* params.SMask_is_CIE = gs_color_space_is_CIE(pgs->color_space); */  /* See comments in gs_begin_transparency_mask */
     params.SMask_is_CIE = false; 
     params.Background_components = ptmp->Background_components;
     memcpy(params.Background, ptmp->Background, l);
@@ -537,15 +536,21 @@
 	    (ptmp->TransferFunction == mask_transfer_identity);
     params.mask_is_image = mask_is_image;
     params.replacing = ptmp->replacing;
-    /* Note that the SMask buffer may have a different 
-       numcomps than the device buffer */
-    params.group_color_numcomps = cs_num_components(pgs->color_space);
 
-    if_debug9('v', "[v](0x%lx)gs_begin_transparency_mask [%g %g %g %g]\n\
-      subtype = %d  Background_components = %d Num_grp_clr_comp = %d  %s\n",
+    /* The eventual state that we want this smask to be moved to
+       is always gray.  This should provide us with a significant 
+       speed improvement over the old code.  This does not keep us
+       from having groups within the softmask getting blended in different
+       color spaces, it just makes the final space be gray, which is what
+       we will need to get to eventually anyway. In this way we avoid a 
+       final color conversion on a potentially large buffer. */
+    blend_color_space = gs_cspace_new_DeviceGray(pgs->memory);
+    blend_color_space->cmm_icc_profile_data = pgs->icc_manager->default_gray;
+    rc_increment(pgs->icc_manager->default_gray);
+    if_debug8('v', "[v](0x%lx)gs_begin_transparency_mask [%g %g %g %g]\n\
+      subtype = %d  Background_components = %d %s\n",
 	      (ulong)pgs, pbbox->p.x, pbbox->p.y, pbbox->q.x, pbbox->q.y,
 	      (int)ptmp->subtype, ptmp->Background_components,
-              params.group_color_numcomps,
 	      (ptmp->TransferFunction == mask_transfer_identity ? "no TR" :
 	       "has TR"));
 
@@ -557,47 +562,20 @@
 	ptmp->TransferFunction(in, &out, ptmp->TransferFunction_data);
 	params.transfer_fn[i] = (byte)floor((double)(out * 255 + 0.5));
     }
-
-    /* If we have a CIE space & a luminosity subtype
-       we will need to do our concretization
-       to CIEXYZ so that we can obtain the proper 
-       luminance value.  This is what SHOULD happen
-       according to the spec.  However AR does not 
-       follow this.  It always seems to do the soft mask
-       creation in the device space.  For this reason
-       we will do that too. SMask_is_CIE is always false for now */
-
-    /* The blending procs are currently based upon the device type.
-       We need to have them based upon the current color space */
-
     /* Note:  This function is called during the c-list writer side. */ 
-
-    blend_color_space = pgs->color_space;
-
-    if ( gs_color_space_is_ICC(blend_color_space) ) {
-
+    if ( blend_color_space->cmm_icc_profile_data != NULL ) {
     /* 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.
-       */
-
+       to write this color space into the clist. */
         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 {
-
-
         num_components = cs_num_components(blend_color_space);
         switch (abs(num_components)) {
-
             case 1:				
                 params.group_color = GRAY_SCALE;       
                 params.group_color_numcomps = 1;  /* Need to check */
@@ -617,11 +595,9 @@
                    transform */
             return_error(gs_error_rangecheck);
             break;
-
          }    
-
     }
-
+    rc_decrement_only_cs(blend_color_space, "gs_begin_transparency_mask");
     return gs_state_update_pdf14trans(pgs, &params);
 }
 

Modified: branches/icc_work/base/gxblend.c
===================================================================
--- branches/icc_work/base/gxblend.c	2010-03-18 20:30:00 UTC (rev 10942)
+++ branches/icc_work/base/gxblend.c	2010-03-18 20:34:24 UTC (rev 10943)
@@ -18,7 +18,10 @@
 #include "gstparam.h"
 #include "gxblend.h"
 #include "gxcolor2.h"
+#include "gsicccache.h"
+#include "gsiccmanage.h"
 
+
 typedef int art_s32;
 
 #if RAW_DUMP
@@ -34,184 +37,159 @@
 /* Note, data is planar */
 
 void 
-Smask_Luminosity_Mapping(int num_rows, int num_cols, int n_chan, int row_stride, 
-                         int plane_stride, byte *dst, const byte *src, bool isadditive,
+smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride, 
+                         int plane_stride, byte *src, const byte *dst, bool isadditive,
                          bool SMask_is_CIE, gs_transparency_mask_subtype_t SMask_SubType)
 {
-
     int x,y;
     int mask_alpha_offset,mask_C_offset,mask_M_offset,mask_Y_offset,mask_K_offset;
     int mask_R_offset,mask_G_offset,mask_B_offset;
     byte *dstptr;
 
 #if RAW_DUMP
-
     dump_raw_buffer(num_rows, row_stride, n_chan,
                 plane_stride, row_stride, 
                 "Raw_Mask", src);
 
     global_index++;
-
 #endif
-
     dstptr = dst;
-
     /* If we are CIE AND subtype is Luminosity then we should just grab the Y channel */
-
-    if ( SMask_is_CIE && SMask_SubType == TRANSPARENCY_MASK_Luminosity ){
-
- 
+    if ( SMask_is_CIE && SMask_SubType == TRANSPARENCY_MASK_Luminosity ) {
         memcpy(dst, &(src[plane_stride]), plane_stride);
         return;
-
     }
-
     /* If we are alpha type, then just grab that */ 
     /* We need to optimize this so that we are only drawing alpha in the rect fills */
-
-    if ( SMask_SubType == TRANSPARENCY_MASK_Alpha ){
-
+    if ( SMask_SubType == TRANSPARENCY_MASK_Alpha ) {
         mask_alpha_offset = (n_chan - 1) * plane_stride;
         memcpy(dst, &(src[mask_alpha_offset]), plane_stride);
         return;
-
     }
-
     /* To avoid the if statement inside this loop, 
     decide on additive or subractive now */
-
-    if (isadditive || n_chan == 2)
-    {
-
+    if (isadditive || n_chan == 2) {
         /* Now we need to split Gray from RGB */
-
-        if( n_chan == 2 )
-        {
+        if( n_chan == 2 ) {
             /* Gray Scale case */
-
            mask_alpha_offset = (n_chan - 1) * plane_stride;
            mask_R_offset = 0;
-
-            for ( y = 0; y < num_rows; y++ )
-            {
-     
-                for ( x = 0; x < num_cols; x++ ){
-
+            for ( y = 0; y < num_rows; y++ ) {
+                for ( x = 0; x < num_cols; x++ ) {
                     /* With the current design this will indicate if 
                     we ever did a fill at this pixel. if not then move on.
                     This could have some serious optimization */
-                               
 	            if (src[x + mask_alpha_offset] != 0x00) {
-
                         dstptr[x] = src[x + mask_R_offset];
-
                     } 
-
                 }
-
                dstptr += row_stride;
                mask_alpha_offset += row_stride;
                mask_R_offset += row_stride;
-
             }
-
         } else {
-
-
-
             /* RGB case */
-
            mask_R_offset = 0;
            mask_G_offset = plane_stride;
            mask_B_offset = 2 * plane_stride;
            mask_alpha_offset = (n_chan - 1) * plane_stride;
-
-            for ( y = 0; y < num_rows; y++ )
-            {
-     
-               for ( x = 0; x < num_cols; x++ ){
-
+            for ( y = 0; y < num_rows; y++ ) {
+               for ( x = 0; x < num_cols; x++ ) {
                     /* With the current design this will indicate if 
                     we ever did a fill at this pixel. if not then move on */
-                               
 	            if (src[x + mask_alpha_offset] != 0x00) {
-
 	                /* Get luminosity of Device RGB value */
-
                         float temp;
-
                         temp = ( 0.30 * src[x + mask_R_offset] + 
                             0.59 * src[x + mask_G_offset] + 
                             0.11 * src[x + mask_B_offset] );
-     
                         temp = temp * (1.0 / 255.0 );  /* May need to be optimized */
 	                dstptr[x] = float_color_to_byte_color(temp);
-
                     } 
-
                 }
-
                dstptr += row_stride;
                mask_alpha_offset += row_stride;
                mask_R_offset += row_stride;
                mask_G_offset += row_stride;
                mask_B_offset += row_stride;
-
             }
-            
         }
-
     } else {
-
        /* CMYK case */
-
        mask_alpha_offset = (n_chan - 1) * plane_stride;
        mask_C_offset = 0;
        mask_M_offset = plane_stride;
        mask_Y_offset = 2 * plane_stride;
        mask_K_offset = 3 * plane_stride;
-
-       for ( y = 0; y < num_rows; y++ ){
-
-            for ( x = 0; x < num_cols; x++ ){
-
+       for ( y = 0; y < num_rows; y++ ) {
+            for ( x = 0; x < num_cols; x++ ) {
                 /* With the current design this will indicate if 
                 we ever did a fill at this pixel. if not then move on */
-                            
-	        if (src[x + mask_alpha_offset] != 0x00){
-
+	        if (src[x + mask_alpha_offset] != 0x00) {
                   /* PDF spec says to use Y = 0.30 (1 - C)(1 - K) + 
                   0.59 (1 - M)(1 - K) + 0.11 (1 - Y)(1 - K) */
                     /* For device CMYK */
-
                     float temp;
-
                     temp = ( 0.30 * ( 0xff - src[x + mask_C_offset]) + 
                         0.59 * ( 0xff - src[x + mask_M_offset]) + 
                         0.11 * ( 0xff - src[x + mask_Y_offset]) ) * 
                         ( 0xff - src[x + mask_K_offset]);
-
                     temp = temp * (1.0 / 65025.0 );  /* May need to be optimized */
-
 	            dstptr[x] = float_color_to_byte_color(temp);
-
                 } 
- 
             }
-
            dstptr += row_stride;
            mask_alpha_offset += row_stride;
            mask_C_offset += row_stride;
            mask_M_offset += row_stride;
            mask_Y_offset += row_stride;
            mask_K_offset += row_stride;
-
         }
+    }
+}
 
+void smask_copy(int num_rows, int num_cols, int row_stride, 
+                        byte *src, const byte *dst)
+{
+    int y;
+    byte *dstptr,*srcptr;
 
+    dstptr = dst;
+    srcptr = src;
+    for ( y = 0; y < num_rows; y++ ) {
+        memcpy(dstptr,srcptr,num_cols);
+        dstptr += row_stride;
+        srcptr += row_stride;
     }
+}
 
+void smask_icc(int num_rows, int num_cols, int n_chan, int row_stride, 
+                 int plane_stride, byte *src, const byte *dst, 
+                 gsicc_link_t *icclink)
+{
+    gsicc_bufferdesc_t input_buff_desc;
+    gsicc_bufferdesc_t output_buff_desc;
 
+#if RAW_DUMP
+    dump_raw_buffer(num_rows, row_stride, n_chan,
+                plane_stride, row_stride, 
+                "Raw_Mask_ICC", src);
+    global_index++;
+#endif
+/* 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 */
+
+    gsicc_init_buffer(&input_buff_desc, n_chan-1, 1,
+                  false, false, true, plane_stride, row_stride,
+                  num_rows, num_cols);
+    gsicc_init_buffer(&output_buff_desc, 1, 1,
+                  false, false, true, plane_stride, 
+                  row_stride, num_rows, num_cols);
+    /* Transform the data */
+    gscms_transform_color_buffer(icclink, &input_buff_desc, 
+                        &output_buff_desc, src, dst);
 }
 
 void

Modified: branches/icc_work/base/gxblend.h
===================================================================
--- branches/icc_work/base/gxblend.h	2010-03-18 20:30:00 UTC (rev 10942)
+++ branches/icc_work/base/gxblend.h	2010-03-18 20:34:24 UTC (rev 10943)
@@ -96,12 +96,14 @@
 typedef pdf14_parent_cs_params_s pdf14_parent_cs_params_t;
 
 /* This function is used for mapping Smask CMYK or RGB data to a monochrome alpha buffer */
-
-void Smask_Luminosity_Mapping(int num_rows, int num_cols, int n_chan, int row_stride, 
-                         int plane_stride, byte *dst, const byte *src, bool isadditive,
+void smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride, 
+                         int plane_stride, byte *src, const byte *des, bool isadditive,
                             bool SMask_is_CIE, gs_transparency_mask_subtype_t SMask_SubType);
-
-
+void smask_copy(int num_rows, int num_cols, int row_stride, 
+                         byte *src, const byte *des);
+void smask_icc(int num_rows, int num_cols, int n_chan, int row_stride, 
+                         int plane_stride, byte *src, const byte *des, 
+                         gsicc_link_t *icclink);
 /**
  * art_blend_pixel: Compute PDF 1.4 blending function.
  * @dst: Where to store resulting pixel.

Modified: branches/icc_work/base/lib.mak
===================================================================
--- branches/icc_work/base/lib.mak	2010-03-18 20:30:00 UTC (rev 10942)
+++ branches/icc_work/base/lib.mak	2010-03-18 20:34:24 UTC (rev 10943)
@@ -2649,7 +2649,8 @@
 	$(GLCC) $(GLO_)gximag3x.$(OBJ) $(C_) $(GLSRC)gximag3x.c
 
 $(GLOBJ)gxblend.$(OBJ) : $(GLSRC)gxblend.c $(GX) $(memory__h)\
- $(gstparam_h) $(gxblend_h) $(gxcolor2_h) 
+ $(gstparam_h) $(gxblend_h) $(gxcolor2_h) $(gsicccache_h)\
+ $gsiccmanage_h)
 	$(GLCC) $(GLO_)gxblend.$(OBJ) $(C_) $(GLSRC)gxblend.c
 
 $(GLOBJ)gxblend1.$(OBJ) : $(GLSRC)gxblend1.c $(GX) $(memory__h)\



More information about the gs-commits mailing list