[gs-cvs] rev 9405 - branches/smask_work/base

mvrhel at ghostscript.com mvrhel at ghostscript.com
Mon Jan 26 16:49:22 PST 2009


Author: mvrhel
Date: 2009-01-26 16:49:18 -0800 (Mon, 26 Jan 2009)
New Revision: 9405

Modified:
   branches/smask_work/base/gdevdevn.c
   branches/smask_work/base/gdevp14.c
   branches/smask_work/base/gscolorbuffer.c
   branches/smask_work/base/gxblend.h
Log:
Fix for the soft mask branch to work properly in the presence of spot colors and separation devices.  


DETAILS: When a device supports spot colors and the source file has a transparency group, per the PDF spec the group color space is effectively ignored and the spot colors are blended in the individual color planes.  This is NOT true for the group color of a soft mask.  In that case, the group color is used and all spot color should be mapped via the alternate color space to the group color.  This blended group eventually is squashed to a luminance channel to be used as a mask.

Modified: branches/smask_work/base/gdevdevn.c
===================================================================
--- branches/smask_work/base/gdevdevn.c	2009-01-27 00:18:29 UTC (rev 9404)
+++ branches/smask_work/base/gdevdevn.c	2009-01-27 00:49:18 UTC (rev 9405)
@@ -471,7 +471,8 @@
 	        if (page_spot_colors < -1)
 		    return_error(gs_error_rangecheck);
 	        if (page_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS)
-		    page_spot_colors = GX_DEVICE_COLOR_MAX_COMPONENTS;
+		    page_spot_colors = GX_DEVICE_COLOR_MAX_COMPONENTS-4;  
+                    /* Need to leave room for the 4 process colors */
         }
         /* 
          * The DeviceN device can have zero components if nothing has been

Modified: branches/smask_work/base/gdevp14.c
===================================================================
--- branches/smask_work/base/gdevp14.c	2009-01-27 00:18:29 UTC (rev 9404)
+++ branches/smask_work/base/gdevp14.c	2009-01-27 00:49:18 UTC (rev 9405)
@@ -894,10 +894,6 @@
 
     buf->saved = ctx->stack;
     ctx->stack = buf;
-     /* windoze memory checking */
-  /*  z = _CrtCheckMemory();
-	   if (z != 1)
-        z = 0;  */
 
     /* Soft Mask related information so we know how to 
        compute luminosity when we pop the soft mask */
@@ -1971,17 +1967,31 @@
     double alpha = pis->opacity.alpha * pis->shape.alpha;
     gs_int_rect rect;
     int code;
-	bool isolated;
+    bool isolated;
+    bool sep_target = (strcmp(pdev->dname, "PDF14cmykspot") == 0);
+    int group_color_numcomps;
 
+    /* If the target device supports separations, then 
+       we should should NOT create the group.  The exception to this 
+       rule would be if we just popped a transparency mask */
+
     code = compute_group_device_int_rect(pdev, &rect, pbbox, pis);
+
     if (code < 0)
 	return code;
     if_debug4('v', "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d\n",
 	      ptgp->Isolated, ptgp->Knockout, alpha, pis->blend_mode);
 
-     /* If needed, update the color mapping procs */
-    code = pdf14_update_device_color_procs(dev,ptgp->group_color,pis);
+     /* If needed, update the color mapping procs. But only if we dont have a sep device.
+        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,ptgp->group_color,pis);
+        group_color_numcomps = ptgp->group_color_numcomps;
+    } else {
+        group_color_numcomps = pdev->color_info.num_components;
+    }
+
     /* Note that our initial device buffer may have had a different color space
        than the first transparency group.  In such a case, we really should force
        this first group to be isolated, anytime that the parent color space is 
@@ -2006,7 +2016,7 @@
 					 (byte)floor (255 * alpha + 0.5),
 					 (byte)floor (255 * pis->shape.alpha + 0.5),
 					 pis->blend_mode, ptgp->idle,
-					 ptgp->mask_id,ptgp->group_color_numcomps);
+					 ptgp->mask_id,group_color_numcomps);
     return code;
 }
 
@@ -2502,6 +2512,9 @@
     if (code < 0)
 	return code;
 
+    /* Note that the soft mask always follows the group color requirements even
+       when we have a separable device */
+
     return pdf14_push_transparency_mask(pdev->ctx, &rect, bg_alpha,
 					transfer_fn, ptmp->idle, ptmp->replacing,
 					ptmp->mask_id, ptmp->subtype, 
@@ -4555,6 +4568,7 @@
 {
     pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
     int code;
+    bool sep_target;
 
     /* We only handle a few PDF 1.4 transparency operations 4 */
     if (gs_is_pdf14trans_compositor(pct)) {
@@ -4640,11 +4654,15 @@
 
                 pdf14_push_parent_color(dev, pis);
 
-                /* Now update the device procs */
+                /* Now update the device procs. Not 
+                   if we have a sep target though */
 
-               code = pdf14_update_device_color_procs_push_c(dev,
-			      pdf14pct->params.group_color,pis);
+                sep_target = (strcmp(pdev->dname, "PDF14clistcustom") == 0) || (strcmp(pdev->dname, "PDF14clistcmykspot") == 0);
 
+                if (!sep_target)
+                   code = pdf14_update_device_color_procs_push_c(dev,
+			          pdf14pct->params.group_color,pis);
+
                /* Note that our initial device buffer may have had a different color space
                    than the first transparency group.  In such a case, we really should force
                    this first group to be isolated, anytime that the parent color space is 

Modified: branches/smask_work/base/gscolorbuffer.c
===================================================================
--- branches/smask_work/base/gscolorbuffer.c	2009-01-27 00:18:29 UTC (rev 9404)
+++ branches/smask_work/base/gscolorbuffer.c	2009-01-27 00:49:18 UTC (rev 9405)
@@ -117,99 +117,155 @@
     num_rows = rect.q.y - rect.p.y;
     num_cols = rect.q.x - rect.p.x;
 
-    /* Pick the mapping to use */
+    /* Check for spot + cmyk case */
 
-    switch (input_num_color){
+    if (output_num_color > 4)
+    {
 
-        case 1:
-            if (output_num_color == 3){
-                color_remap = gray_to_rgb;
-            } else {
+        /* To CMYK always */
+        switch (input_num_color){
+
+            case 1:
                 color_remap = gray_to_cmyk;
-            }
-            break;
-        case 3:
-            if (output_num_color == 1){
-                color_remap = rgb_to_gray;
-            } else {
+                break;
+            case 3:
                 color_remap = rgb_to_cmyk;
-            }
-            break;
+                break;
 
-        case 4:
-            if (output_num_color == 1){
-                 color_remap = cmyk_to_gray;              
-            } else {
-                color_remap = cmyk_to_rgb;
-            }
-            break;
+            case 4:
+                color_remap = NULL;        /* Copy data */      
+                break;
 
-        default:
-        
-            /* Need to consider the spot color case */
+            default:
+            
+                /* Should never be here.  Groups must
+                   be gray, rgb or CMYK.   Exception
+                   may be ICC with XPS */
 
-            break;
+                break;
 
+        }
+
+
+
+
+    } else {
+
+        /* Pick the mapping to use */
+
+        switch (input_num_color){
+
+            case 1:
+                if (output_num_color == 3){
+                    color_remap = gray_to_rgb;
+                } else {
+                    color_remap = gray_to_cmyk;
+                }
+                break;
+            case 3:
+                if (output_num_color == 1){
+                    color_remap = rgb_to_gray;
+                } else {
+                    color_remap = rgb_to_cmyk;
+                }
+                break;
+
+            case 4:
+                if (output_num_color == 1){
+                     color_remap = cmyk_to_gray;              
+                } else {
+                    color_remap = cmyk_to_rgb;
+                }
+                break;
+
+            default:
+            
+                /* Should never be here.  Groups must
+                   be gray, rgb or CMYK.   Until we
+                   have ICC working here with XPS */
+
+                break;
+
+        }
+
     }
 
     /* data is planar */
-   max_num_channels = max(input_num_color ,output_num_color) + num_noncolor_planes;
-   for(z = 0; z<max_num_channels; z++){ 
+    max_num_channels = max(input_num_color ,output_num_color) + num_noncolor_planes;
+    for(z = 0; z<max_num_channels; z++){ 
 
        plane_offset[z] = z * plane_stride;
 
-   }
+    }
 
-   alpha_offset_in = input_num_color*plane_stride;
+    if (color_remap == NULL){
 
-    for ( y = 0; y < num_rows; y++ ){
+        /* Blending group was CMYK, output is CMYK + spot */
 
-       for ( x = 0; x < num_cols; x++ ){
+       memcpy(outputbuffer, inputbuffer, 4*plane_stride);
 
-            /* If the source alpha is transparent, then move on */
-                       
-            if (inputbuffer[x + alpha_offset_in] != 0x00) {
+       /* Add any data that are beyond the standard color data (e.g. alpha) */
 
-                /* grab the input */
-                for (z = 0; z<input_num_color; z++){
+       if (num_noncolor_planes>0)
+           memcpy(&(outputbuffer[plane_offset[output_num_color]]), 
+           &(inputbuffer[plane_offset[input_num_color]]), num_noncolor_planes*plane_stride);
 
-                    input_vector[z] = inputbuffer[x+plane_offset[z]];
+    } else {
 
-                }
+        /* Have to remap */
 
-                /* convert */
- 
-               color_remap(input_vector,output_vector);
+       alpha_offset_in = input_num_color*plane_stride;
 
-               /* store the output */
-               for (z = 0; z<output_num_color; z++){
+        for ( y = 0; y < num_rows; y++ ){
 
-                    outputbuffer[x+plane_offset[z]] = output_vector[z];
+           for ( x = 0; x < num_cols; x++ ){
 
-               }
+                /* If the source alpha is transparent, then move on */
+                           
+                if (inputbuffer[x + alpha_offset_in] != 0x00) {
 
-               /* Add any that are beyond the standard color data */
+                    /* grab the input */
+                    for (z = 0; z<input_num_color; z++){
 
-                for(z = 0; z< num_noncolor_planes; z++){
+                        input_vector[z] = inputbuffer[x+plane_offset[z]];
 
-                    outputbuffer[x + plane_offset[output_num_color+z]] = inputbuffer[x + plane_offset[input_num_color+z]];
+                    }
 
+                    /* convert */
+     
+                   color_remap(input_vector,output_vector);
+
+                   /* store the output */
+                   for (z = 0; z<output_num_color; z++){
+
+                        outputbuffer[x+plane_offset[z]] = output_vector[z];
+
+                   }
+
+                   /* Add any that are beyond the standard color data */
+
+                    for(z = 0; z< num_noncolor_planes; z++){
+
+                        outputbuffer[x + plane_offset[output_num_color+z]] = inputbuffer[x + plane_offset[input_num_color+z]];
+
+                    }
+
                 }
 
-            }
+           }
 
-       }
+           /* update our positions */
 
-       /* update our positions */
+            for(z = 0; z<max_num_channels; z++){ 
 
-        for(z = 0; z<max_num_channels; z++){ 
+               plane_offset[z] += row_stride;
 
-           plane_offset[z] += row_stride;
+            }
+            alpha_offset_in += row_stride;
 
+
         }
-        alpha_offset_in += row_stride;
 
-
     }
 
 

Modified: branches/smask_work/base/gxblend.h
===================================================================
--- branches/smask_work/base/gxblend.h	2009-01-27 00:18:29 UTC (rev 9404)
+++ branches/smask_work/base/gxblend.h	2009-01-27 00:49:18 UTC (rev 9405)
@@ -25,7 +25,7 @@
 
 /* #define DUMP_TO_PNG */
 
-#define	PDF14_MAX_PLANES GX_DEVICE_COLOR_MAX_COMPONENTS+1  /* Needed for alpha channel */
+#define	PDF14_MAX_PLANES GX_DEVICE_COLOR_MAX_COMPONENTS+3  /* Needed for alpha channel, shape, group alpha */
 
 typedef bits16 ArtPixMaxDepth;
 



More information about the gs-cvs mailing list