[gs-cvs] rev 8001 - in trunk/gs: lib src

leonardo at ghostscript.com leonardo at ghostscript.com
Thu May 24 11:06:59 PDT 2007


Author: leonardo
Date: 2007-05-24 11:06:57 -0700 (Thu, 24 May 2007)
New Revision: 8001

Modified:
   trunk/gs/lib/pdf_draw.ps
   trunk/gs/lib/pdf_main.ps
   trunk/gs/src/gscie.c
   trunk/gs/src/gscie.h
   trunk/gs/src/gsciemap.c
   trunk/gs/src/gscolor3.c
   trunk/gs/src/gsicc.c
   trunk/gs/src/gsshade.c
   trunk/gs/src/gsshade.h
   trunk/gs/src/gxcie.h
   trunk/gs/src/int.mak
   trunk/gs/src/lib.mak
   trunk/gs/src/zcrd.c
   trunk/gs/src/zshade.c
Log:
Fix (shadings) : Reuse shadings while a PDF interpretation.

DETAILS : 

Bug 689211 "PDF interpreter creates redundant shadings".

This partially improves performance for the test case of 
the bug 689189 "PDF fails with /unregistered in --shfill--".

The test case defines 79 shadings. While interpreting it 
the old code calls zbuildshading2 9600+ times.

1. Improved resolveshading with reusing old shadings (pdf_draw.ps).
2. Improved 'sh' with reusing old shading dictionaries (pdf_draw.ps).
3. Renamed gx_currentciecaches with gx_unshare_cie_caches,
   because the old name does not comply to the function body.
4. Defined a new function gx_currentciecaches.
5. The macro CIE_CHECK_RENDERING is replaced with a new function 
   gx_cie_check_rendering_inline. The new code also checks 
   the consistency of cie_joint_caches with the color space
   by checking the id, and requests refilling the cache if necessary.
   Note it can cause the PS interpreter callout with EncodeLMN, etc.
6. IMPORTANT: The new field gs_shading_params_t::cie_joint_caches
   saves the pointer to gs_state::cie_joint_caches.
   It is used in .shfill - see zshade.c .
   Debugged with Bug688631.pdf .
7. NOTE: *gs_shading_params_t::cie_joint_caches may be left unreleased
   when the shading releases. The garbager will release it.
   This happens with PS interpreter only.
8. NOTE: We do not make cie_joint_caches be a property of color space,
   rather it would look natural. The reason is that this large structure 
   is needed to save with shadings only. Saving it for any color space
   would spend too big RAM.
9. NOTE: Due to historic reason gs_setcolorspace leaves cie_joint_caches
   unchanged. It may cause problems when gx_color_space_needs_cie_caches
   is true. Postscript interpreter has a special workaround for it in
   gs/lib/gs_cspace.ps . Other interpreters may need an additional support
   when they use CIE spaces directly or indirectly. 
   Likely this feature is not properly documented.
10. NOTE: The change to pdf_draw.ps cases an additional RAM expence for
   PDF interpretation. It is caused by saving all built shadings
   until the document finishes. It includes the expence for extra copies of
   cie_joint_caches. The new procedure .free_page_resources frees
   shadings from page Resources after page finishes.
   However this patch does not implement that for 
   other local resources, such as form Resources, etc.
   It may need a further improvement.

EXPECTED DIFFERENCES :

None.


Modified: trunk/gs/lib/pdf_draw.ps
===================================================================
--- trunk/gs/lib/pdf_draw.ps	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/lib/pdf_draw.ps	2007-05-24 18:06:57 UTC (rev 8001)
@@ -144,18 +144,29 @@
 .dicttomark readonly def
 
 /resolveshading {	% <shadingstream> resolveshading <shading>
-  PDFfile fileposition exch
-  mark exch {
-    oforce //shrdict 2 index .knownget { exec } if
-  } forall .dicttomark
-  dup /ShadingType get 4 ge {
-    dup dup true resolvestream
+  dup /.shading_dict .knownget {
+    exch pop 
+    dup /ShadingType get 4 ge {
+      dup /DataSource get 0 setfileposition
+    } if
+  } {
+    dup
+    PDFfile fileposition exch
+    mark exch {
+      oforce //shrdict 2 index .knownget { exec } if
+    } forall .dicttomark
+    dup /ShadingType get 4 ge {
+      dup dup true resolvestream
 		% Make a reusable stream so that the shading doesn't
 		% reposition PDFfile at unexpected times.
-    /ReusableStreamDecode filter /DataSource exch put
-  } if exch PDFfile exch setfileposition
+      /ReusableStreamDecode filter /DataSource exch put
+    } if 
+    exch PDFfile exch setfileposition
+    dup 3 1 roll /.shading_dict exch put
+  } ifelse
 } bdef
-/resolvesh {		% <shname> resolveshading <shading>
+/resolvesh {		% <shname> resolvesh <shading>
+			% <shname> resolvesh <null>
   Page /Shading rget {
     resolveshading
   } {
@@ -822,7 +833,18 @@
   /b* { b* } def
   /W { W } def
   /W* { W* } def
-  /sh { setfillstate resolvesh shfill } def
+  /sh { setfillstate resolvesh 
+        gsave 0 .setoverprintmode 
+        dup /.shading .knownget {
+          exch 
+          pop
+        } {
+          dup
+          .buildshading
+          dup 3 1 roll /.shading exch put
+        } ifelse
+        .shfill grestore 
+      } def
 end
 
 % ---------------- XObjects ---------------- %

Modified: trunk/gs/lib/pdf_main.ps
===================================================================
--- trunk/gs/lib/pdf_main.ps	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/lib/pdf_main.ps	2007-05-24 18:06:57 UTC (rev 8001)
@@ -1307,6 +1307,20 @@
   pop currentdict end setpagedevice
 } bind def
 
+/.free_page_resources {   % - .free_page_resources -
+  Page /Resources pget {
+    /Shading knownoget {
+      { dup type /dicttype eq {
+          dup /.shading_dict known {
+            dup /.shading_dict undef
+          } if
+        } if
+        pop pop
+      } forall
+    } if
+  } if
+} bind def
+
 /pdfshowpage_finish {	% <pagedict> pdfshowpage_finish -
    save /PDFSave exch store
    /PDFdictstackcount countdictstack store
@@ -1387,6 +1401,7 @@
   } {
     showpagecontents
   } ifelse
+  .free_page_resources
   % todo: mixing drawing ops outside the device filter could cause
   % problems, for example with the pnga device.
   endpage

Modified: trunk/gs/src/gscie.c
===================================================================
--- trunk/gs/src/gscie.c	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/src/gscie.c	2007-05-24 18:06:57 UTC (rev 8001)
@@ -787,13 +787,13 @@
 
 /* Unshare (allocating if necessary) the joint caches. */
 gx_cie_joint_caches *
-gx_currentciecaches(gs_state * pgs)
+gx_unshare_cie_caches(gs_state * pgs)
 {
     gx_cie_joint_caches *pjc = pgs->cie_joint_caches;
 
     rc_unshare_struct(pgs->cie_joint_caches, gx_cie_joint_caches,
 		      &st_joint_caches, pgs->memory,
-		      return 0, "gx_currentciecaches");
+		      return 0, "gx_unshare_cie_caches");
     if (pgs->cie_joint_caches != pjc) {
 	pjc = pgs->cie_joint_caches;
 	pjc->cspace_id = pjc->render_id = gs_no_id;
@@ -802,6 +802,12 @@
     return pjc;
 }
 
+gx_cie_joint_caches *
+gx_currentciecaches(gs_state * pgs)
+{
+    return pgs->cie_joint_caches;
+}
+
 /* Compute the parameters for loading a cache, setting base and factor. */
 /* This procedure is idempotent. */
 void
@@ -1205,7 +1211,7 @@
 int
 gs_cie_cs_complete(gs_state * pgs, bool init)
 {
-    gx_cie_joint_caches *pjc = gx_currentciecaches(pgs);
+    gx_cie_joint_caches *pjc = gx_unshare_cie_caches(pgs);
 
     if (pjc == 0)
 	return_error(gs_error_VMerror);
@@ -1484,6 +1490,7 @@
     pjc->skipDecodeABC = pabc != 0 && pabc->caches.skipABC;
     /* Mark the joint caches as completed. */
     pjc->remap_finish = gx_cie_xyz_remap_finish;
+    pjc->cspace_id = pcs->id;
     pjc->status = CIE_JC_STATUS_COMPLETED;
     pis->cie_joint_caches = pjc;
     /*
@@ -1600,3 +1607,24 @@
 	mat->cv.v == 1.0 && is_fzero2(mat->cv.u, mat->cv.w) &&
 	mat->cw.w == 1.0 && is_fzero2(mat->cw.u, mat->cw.v);
 }
+
+bool 
+gx_color_space_needs_cie_caches(const gs_color_space * pcs)
+{
+    switch (pcs->type->index) {
+    	case gs_color_space_index_CIEDEFG:
+    	case gs_color_space_index_CIEDEF:
+    	case gs_color_space_index_CIEABC:
+    	case gs_color_space_index_CIEA:
+    	case gs_color_space_index_CIEICC:
+	    return true;
+	case gs_color_space_index_DevicePixel:
+    	case gs_color_space_index_DeviceN:
+    	case gs_color_space_index_Separation:
+    	case gs_color_space_index_Indexed:
+    	case gs_color_space_index_Pattern:
+	    return gx_color_space_needs_cie_caches(pcs->base_space);
+	default:
+	    return false;
+    }
+}

Modified: trunk/gs/src/gscie.h
===================================================================
--- trunk/gs/src/gscie.h	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/src/gscie.h	2007-05-24 18:06:57 UTC (rev 8001)
@@ -597,7 +597,7 @@
   int proc(cie_cached_vector3 vec3, frac *pconc,\
 	   const gs_imager_state *pis, const gs_color_space *pcs)
 
-typedef struct gx_cie_joint_caches_s {
+struct gx_cie_joint_caches_s {
     /*
      * The first 4 members are the "key" in the cache.  They behave as
      * follows:
@@ -635,8 +635,14 @@
     bool skipPQR;
     gx_cie_vector_cache3_t TransformPQR;	/* mult. by PQR_inverse_LMN */
     bool skipEncodeLMN;
-} gx_cie_joint_caches;
+};
 
+#ifndef gx_cie_joint_caches_DEFINED
+#define gx_cie_joint_caches_DEFINED
+typedef struct gx_cie_joint_caches_s gx_cie_joint_caches;
+#endif
+
+
 #define private_st_joint_caches() /* in gscie.c */\
   gs_private_st_simple(st_joint_caches, gx_cie_joint_caches,\
     "gx_cie_joint_caches")
@@ -674,6 +680,7 @@
 void gs_cie_def_complete(gs_cie_def *);
 void gs_cie_abc_complete(gs_cie_abc *);
 void gs_cie_a_complete(gs_cie_a *);
+gx_cie_joint_caches *gx_unshare_cie_caches(gs_state *);
 gx_cie_joint_caches *gx_currentciecaches(gs_state *);
 const gs_cie_common *gs_cie_cs_common(const gs_state *);
 int gs_cie_cs_complete(gs_state *, bool);
@@ -805,4 +812,6 @@
 /* Serialize common CIE elements. */
 int gx_serialize_cie_common_elements(const gs_color_space * pcs, stream * s);
 
+bool gx_color_space_needs_cie_caches(const gs_color_space * pcs);
+
 #endif /* gscie_INCLUDED */

Modified: trunk/gs/src/gsciemap.c
===================================================================
--- trunk/gs/src/gsciemap.c	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/src/gsciemap.c	2007-05-24 18:06:57 UTC (rev 8001)
@@ -90,6 +90,39 @@
 #  define cie_lookup_map3(pvec, pc, cname) cie_lookup_mult3(pvec, pc)
 #endif
 
+
+/*
+ * Test whether a CIE rendering has been defined; ensure that the joint
+ * caches are loaded.  Note that the procedure may return 1 if no rendering
+ * has been defined.
+ */
+private inline int 
+gx_cie_check_rendering_inline(const gs_color_space * pcs, frac * pconc, const gs_imager_state * pis)
+{
+    if (pis->cie_render == 0) {
+	/* No rendering has been defined yet: return black. */
+	pconc[0] = pconc[1] = pconc[2] = frac_0;
+	return 1;
+    }
+    if (pis->cie_joint_caches->status == CIE_JC_STATUS_COMPLETED) {
+	if (pis->cie_joint_caches->cspace_id != pcs->id)
+	    pis->cie_joint_caches->status = CIE_JC_STATUS_BUILT;
+    }
+    if (pis->cie_joint_caches->status != CIE_JC_STATUS_COMPLETED) {
+	int     code = gs_cie_jc_complete(pis, pcs);
+
+	if (code < 0)
+	    return code;
+    }
+    return 0;
+}
+int 
+gx_cie_check_rendering(const gs_color_space * pcs, frac * pconc, const gs_imager_state * pis)
+{
+    return gx_cie_check_rendering_inline(pcs, pconc, pis);
+}
+
+
 /* Render a CIEBasedDEFG color. */
 int
 gx_concretize_CIEDEFG(const gs_client_color * pc, const gs_color_space * pcs,
@@ -100,11 +133,16 @@
     fixed hijk[4];
     frac abc[3];
     cie_cached_vector3 vec3;
+    int code;
 
     if_debug4('c', "[c]concretize DEFG [%g %g %g %g]\n",
 	      pc->paint.values[0], pc->paint.values[1],
 	      pc->paint.values[2], pc->paint.values[3]);
-    CIE_CHECK_RENDERING(pcs, pconc, pis, return 0);
+    code = gx_cie_check_rendering_inline(pcs, pconc, pis);
+    if (code < 0)
+	return code;
+    if (code == 1)
+	return 0;
 
     /*
      * Apply DecodeDEFG, including restriction to RangeHIJK and scaling to
@@ -158,11 +196,16 @@
     fixed hij[3];
     frac abc[3];
     cie_cached_vector3 vec3;
+    int code;
 
     if_debug3('c', "[c]concretize DEF [%g %g %g]\n",
 	      pc->paint.values[0], pc->paint.values[1],
 	      pc->paint.values[2]);
-    CIE_CHECK_RENDERING(pcs, pconc, pis, return 0);
+    code = gx_cie_check_rendering_inline(pcs, pconc, pis);
+    if (code < 0)
+	return code;
+    if (code == 1)
+	return 0;
 
     /*
      * Apply DecodeDEF, including restriction to RangeHIJ and scaling to
@@ -286,6 +329,7 @@
 {
     frac conc[4];
     cie_cached_vector3 vec3;
+    int code;
 
     if_debug3('c', "[c]remap CIEABC [%g %g %g]\n",
 	      pc->paint.values[0], pc->paint.values[1],
@@ -303,7 +347,11 @@
     }
 #endif
 
-    CIE_CHECK_RENDERING(pcs, conc, pis, goto map3);
+    code = gx_cie_check_rendering_inline(pcs, conc, pis);
+    if (code < 0)
+	return code;
+    if (code == 1)
+	goto map3;
     vec3.u = float2cie_cached(pc->paint.values[0]);
     vec3.v = float2cie_cached(pc->paint.values[1]);
     vec3.w = float2cie_cached(pc->paint.values[2]);
@@ -348,11 +396,16 @@
 {
     const gs_cie_abc *pcie = pcs->params.abc;
     cie_cached_vector3 vec3;
+    int code;
 
     if_debug3('c', "[c]concretize CIEABC [%g %g %g]\n",
 	      pc->paint.values[0], pc->paint.values[1],
 	      pc->paint.values[2]);
-    CIE_CHECK_RENDERING(pcs, pconc, pis, return 0);
+    code = gx_cie_check_rendering_inline(pcs, pconc, pis);
+    if (code < 0)
+	return code;
+    if (code == 1)
+	return 0;
 
     vec3.u = float2cie_cached(pc->paint.values[0]);
     vec3.v = float2cie_cached(pc->paint.values[1]);
@@ -372,9 +425,14 @@
     const gs_cie_a *pcie = pcs->params.a;
     cie_cached_value a = float2cie_cached(pc->paint.values[0]);
     cie_cached_vector3 vlmn;
+    int code;
 
     if_debug1('c', "[c]concretize CIEA %g\n", pc->paint.values[0]);
-    CIE_CHECK_RENDERING(pcs, pconc, pis, return 0);
+    code = gx_cie_check_rendering_inline(pcs, pconc, pis);
+    if (code < 0)
+	return code;
+    if (code == 1)
+	return 0;
 
     /* Apply DecodeA and MatrixA. */
     if (!pis->cie_joint_caches->skipDecodeABC)

Modified: trunk/gs/src/gscolor3.c
===================================================================
--- trunk/gs/src/gscolor3.c	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/src/gscolor3.c	2007-05-24 18:06:57 UTC (rev 8001)
@@ -26,6 +26,7 @@
 #include "gzpath.h"
 #include "gxpaint.h"		/* (requires gx_path) */
 #include "gxshade.h"
+#include "gscie.h"
 
 /* setsmoothness */
 int
@@ -64,6 +65,21 @@
     gx_device_color devc;
     int code;
 
+    /* Must install the shading color space
+       tyo allow check_DeviceN_component_names initialize
+       the color component map.
+     */
+    /* Don't bother with saving the old color space, color,
+       and cie_joint_caches,
+       because .shfill is always called within gsave-grestore -
+       see gs/lib . */
+    code = gs_setcolorspace(pgs, psh->params.ColorSpace);
+    if (code < 0)
+	return 0;
+    if (psh->params.cie_joint_caches != NULL) {
+	pgs->cie_joint_caches = psh->params.cie_joint_caches;
+	rc_increment(pgs->cie_joint_caches);
+    }
     gs_pattern2_init(&pat);
     pat.Shading = psh;
     gs_make_identity(&imat);

Modified: trunk/gs/src/gsicc.c
===================================================================
--- trunk/gs/src/gsicc.c	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/src/gsicc.c	2007-05-24 18:06:57 UTC (rev 8001)
@@ -227,6 +227,7 @@
     cie_cached_vector3      vlmn;
     gs_client_color         lcc = *pcc;
     int                     i, ncomps = picc_info->num_components;
+    int code;
 
     /* use the altenate space concretize if appropriate */
     if (picc == NULL)
@@ -237,7 +238,11 @@
                             pis );
 
     /* set up joint cache as required */
-    CIE_CHECK_RENDERING(pcs, pconc, pis, return 0);
+    code = gx_cie_check_rendering(pcs, pconc, pis);
+    if (code < 0)
+	return code;
+    if (code == 1)
+	return 0;
 
     /* verify and update the stream pointer */
     if (picc_info->file_id != (instrp->read_id | instrp->write_id))

Modified: trunk/gs/src/gsshade.c
===================================================================
--- trunk/gs/src/gsshade.c	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/src/gsshade.c	2007-05-24 18:06:57 UTC (rev 8001)
@@ -135,6 +135,7 @@
 shading_params_init(gs_shading_params_t *params)
 {
     params->ColorSpace = 0;	/* must be set by client */
+    params->cie_joint_caches = 0;
     params->Background = 0;
     params->have_BBox = false;
     params->AntiAlias = false;

Modified: trunk/gs/src/gsshade.h
===================================================================
--- trunk/gs/src/gsshade.h	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/src/gsshade.h	2007-05-24 18:06:57 UTC (rev 8001)
@@ -24,6 +24,11 @@
 #include "gsmatrix.h"
 #include "gxfixed.h"
 
+#ifndef gx_cie_joint_caches_DEFINED
+#define gx_cie_joint_caches_DEFINED
+typedef struct gx_cie_joint_caches_s gx_cie_joint_caches;
+#endif
+
 /* ---------------- Types and structures ---------------- */
 
 /* Define the shading types. */
@@ -44,6 +49,7 @@
  */
 #define gs_shading_params_common\
   gs_color_space *ColorSpace;\
+  gx_cie_joint_caches *cie_joint_caches; /* if ColorSpace is CIE or uses CIE. */\
   gs_client_color *Background;\
   bool have_BBox;\
   gs_rect BBox;\
@@ -94,9 +100,9 @@
 };
 #define ShadingType(psh) ((psh)->head.type)
 #define private_st_shading()	/* in gsshade.c */\
-  gs_private_st_ptrs2(st_shading, gs_shading_t, "gs_shading_t",\
+  gs_private_st_ptrs3(st_shading, gs_shading_t, "gs_shading_t",\
     shading_enum_ptrs, shading_reloc_ptrs,\
-    params.ColorSpace, params.Background)
+    params.ColorSpace, params.cie_joint_caches, params.Background)
 
 /* Define Function-based shading. */
 typedef struct gs_shading_Fb_params_s {

Modified: trunk/gs/src/gxcie.h
===================================================================
--- trunk/gs/src/gxcie.h	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/src/gxcie.h	2007-05-24 18:06:57 UTC (rev 8001)
@@ -56,23 +56,10 @@
 
 /*
  * Test whether a CIE rendering has been defined; ensure that the joint
- * caches are loaded.  Note that the procedure may return if no rendering
- * has been defined, and returns if an error occurs.
+ * caches are loaded.  Note that the procedure may return 1 if no rendering
+ * has been defined.
  */
-#define CIE_CHECK_RENDERING(pcs, pconc, pis, do_exit)                   \
-    BEGIN                                                               \
-        if (pis->cie_render == 0) {                                     \
-            /* No rendering has been defined yet: return black. */      \
-            pconc[0] = pconc[1] = pconc[2] = frac_0;                    \
-            do_exit;                                                    \
-        }                                                               \
-        if (pis->cie_joint_caches->status != CIE_JC_STATUS_COMPLETED) { \
-            int     code = gs_cie_jc_complete(pis, pcs);                \
-                                                                        \
-            if (code < 0)                                               \
-                return code;                                            \
-        }                                                               \
-    END
+int gx_cie_check_rendering(const gs_color_space * pcs, frac * pconc, const gs_imager_state * pis);
 
 /*
  * Do the common remapping operation for CIE color spaces. Returns the

Modified: trunk/gs/src/int.mak
===================================================================
--- trunk/gs/src/int.mak	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/src/int.mak	2007-05-24 18:06:57 UTC (rev 8001)
@@ -1764,7 +1764,7 @@
 
 $(PSOBJ)zshade.$(OBJ) : $(PSSRC)zshade.c $(memory__h) $(OP)\
  $(gscolor2_h) $(gscolor3_h) $(gscspace_h) $(gsfunc3_h)\
- $(gsptype2_h) $(gsshade_h) $(gsstruct_h) $(gsuid_h)\
+ $(gsptype2_h) $(gsshade_h) $(gsstruct_h) $(gsuid_h) $(gscie_h)\
  $(stream_h)\
  $(files_h)\
  $(ialloc_h) $(idict_h) $(idparam_h) $(ifunc_h) $(igstate_h) $(ipcolor_h)\

Modified: trunk/gs/src/lib.mak
===================================================================
--- trunk/gs/src/lib.mak	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/src/lib.mak	2007-05-24 18:06:57 UTC (rev 8001)
@@ -2606,7 +2606,7 @@
 gsfunc3_h=$(GLSRC)gsfunc3.h $(gsdsrc_h) $(gsfunc_h)
 gsshade_h=$(GLSRC)gsshade.h\
  $(gsccolor_h) $(gscspace_h) $(gsdsrc_h) $(gsfunc_h) $(gsmatrix_h)\
- $(gxfixed_h)
+ $(gxfixed_h) $(gscie_h)
 gxshade_h=$(GLSRC)gxshade.h $(gsshade_h) $(gxfixed_h) $(gxmatrix_h) $(stream_h)
 gxshade4_h=$(GLSRC)gxshade4.h
 

Modified: trunk/gs/src/zcrd.c
===================================================================
--- trunk/gs/src/zcrd.c	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/src/zcrd.c	2007-05-24 18:06:57 UTC (rev 8001)
@@ -334,7 +334,7 @@
 		const gs_cie_common *pcie, gs_state * pgs)
 {
     const gs_cie_render *pcrd = gs_currentcolorrendering(pgs);
-    gx_cie_joint_caches *pjc = gx_currentciecaches(pgs);
+    gx_cie_joint_caches *pjc = gx_unshare_cie_caches(pgs);
     gs_ref_memory_t *imem = (gs_ref_memory_t *) gs_state_memory(pgs);
     ref pqr_procs;
     uint space;

Modified: trunk/gs/src/zshade.c
===================================================================
--- trunk/gs/src/zshade.c	2007-05-23 23:33:45 UTC (rev 8000)
+++ trunk/gs/src/zshade.c	2007-05-24 18:06:57 UTC (rev 8001)
@@ -24,6 +24,7 @@
 #include "gsstruct.h"		/* must precede gsshade.h */
 #include "gsshade.h"
 #include "gsuid.h"
+#include "gscie.h"
 #include "stream.h"		/* for files.h */
 #include "files.h"
 #include "ialloc.h"
@@ -158,6 +159,7 @@
 
     check_type(*op, t_dictionary);
     params.ColorSpace = 0;
+    params.cie_joint_caches = 0;
     params.Background = 0;
     /* Collect parameters common to all shading types. */
     {
@@ -223,6 +225,11 @@
     code = (*proc)(i_ctx_p, op, &params, &psh, imemory);
     if (code < 0)
 	goto fail;
+    if (gx_color_space_needs_cie_caches(psh->params.ColorSpace)) {
+	rc_decrement(psh->params.cie_joint_caches, "build_shading");
+	psh->params.cie_joint_caches = gx_currentciecaches(igs);
+	rc_increment(psh->params.cie_joint_caches);
+    }
     make_istruct_new(op, 0, psh);
     return code;
 fail:



More information about the gs-cvs mailing list