[gs-cvs] gs/src

Dan Coby dan at ghostscript.com
Mon Mar 14 10:08:39 PST 2005


Update of /cvs/ghostscript/gs/src
In directory casper2:/tmp/cvs-serv3795/src

Modified Files:
	gdevbbox.c gdevdflt.c gdevmem.c gdevnfwd.c gdevp14.c gdevp14.h 
	gdevprn.c gdevprn.h gdevpsdu.c gsalphac.c gsht.c gsistate.c 
	gsovrc.c gsropc.c gstparam.h gstrans.c gstrans.h gxband.h 
	gxcldev.h gxclimag.c gxclist.c gxclist.h gxclrast.c gxclutil.c 
	gxcmap.c gxcomp.h gxdevcli.h gxdevice.h gxdevmem.h gxdht.h 
	gxdhtserial.c gxistate.h lib.mak zdpnext.c ztrans.c 
Log Message:
Fix for 687696 PDF 1.4 transparency can use large chunks of memory.
Prior to this fix the handling of PDF 1.4 transparency features used one
or more full size image buffers.  With high resolutions and large images,
these buffers can be multiple gigabytes.  As a result, we were not able
to handle these files.

DETAILS:

PDF 1.4 transparency is handled by a device which is inserted into the
device chain.  Prior to this fix, this device was via the 'device filter'
logic.  With this fix, the PDF 1.4 transparency device is inserted via
the compositor device mechanism.  This change was made since the device
filter logic did not allow other devices to control where the PDF 1.4
transparency device is placed in the device chain.  There is a device
proc which implements the create compositor action.  This allows more
control than the device filter logic.

The first step in this fix was to convert the PDF 1.4 transparency
logic to use the create compositor mechanism.  For situations in which
the clist logic is not being used, the PDF 1.4 transparency device is
created and placed in the same location in the device chain as it was put
by the device filter logic.  In this situation, there is very little
logical difference in the operation of the PDF 1.4 transparency.

For situations in which the clist is used, there are two PDF 1.4
compositing devices created.  There is one device before the clist when the
clist is being written.  There is a second device after the clist when
the clist data is being read.

The device before the clist serves two purposes, it provides a means for
implementing the process color model for the PDF 1.4 compositing.  (The
PDF 1.4 compositing may used a different process color model from the output
device.)  Thus this device has color_info and encode/decode color procs
which match the PDF 1.4 blending color space.  This device also ensures
that the PDF 1.4 blending parameters (blend mode, shape, opacity, etc.)
are passed through the clist to the second PDF 1.4 device.

The second PDF 1.4 device (the one when the clist is being read) is the
same PDF 1.4 compositing device which is used when the clist is not being
used.  This is the device which does the blending operations.  Since the
device is after the clist, the buffers that it needs are the size of a
single band instead of the full page.  This device is placed prior to
the memory device which is used for drawing the raster data.

Two changes were made in the 'create compositor' logic.  The imager state
was being passed as a 'const'.  It is no longer const since the PDF 1.4
transparency compositing changes the cmap procs in the imager state to not
use transfer functions during color calculations.  The transfer functions
are applied later (and the cmap procs restored) when blended image data
is output from the PDF 1.4 compositing buffers.

The second change to the create compositor logic is the addition of two
more procedures to the gs_composite_type_t.procs list.  These procedures
are used by the clist device create compositor routines.  The first
is used to create the PDF 1.4 clist write device.  The second saves and
restores the color_info field for the clist device (see below).

Default versions of the added gs_composite_t.procs were also added for
use by the other compositor devices.  The defaults are no-ops.

The clist logic has a few changes.  Since the PDF 1.4 compositor device
may use a different process color model from the output device, the number
of colorants and the depth (bits per pixel) can be different for the PDF
1.4 compositor and the output device.  Thus changes were needed in parts
of the clist logic which assumed that these items were constant during the
processing of the clist.  An extra field was added to the device halftone
to indicate the number of colorants in effect when the device halftone was
created.  This data is included when the halftone is serialized for the
clist.  (Fortunately the PDF 1.4 compositing does not use halftones or
transfer functions.  So the device halftones and transfer functions do
not need to be changed when the PDF 1.4 compositor is installed.)

As previously mentioned the create compositor procedures for the clist
writer and reader now call a couple of compositor specific routines.  These
allow the compositor to implement actions related to the clist device.
(The PDF 1.4 compositor uses these routines to create the 'write clist'
PDF 1.4 compositor and to save and restore the clist device color info.
The color_info field of the clist device is changed to match the process
color model of the PDF 1.4 compositor while the PDF 1.4 compositor is active.

A additional device parameter (PageUsesTransparency) was added.  This
parameter is sent by the PDF interpreter to indicate if PDF 1.4 transparency
will be used on the page.  The banding/no banding decision and the size
of a band includes an estimate of the size of the PDF 1.4 blending buffers
if this parameter is true.  Note:  The estimate of the size of the
blending buffers is not exact since this calculation is made before the
actual number of buffers, the number of blending colors and alpha channels
is known.  Fixed values are used for the estimated buffer size.  This is
still much better than the pervious situation, in which the only the
output raster size was being used.  The blending buffers can easily be
30 or more times larger than the raster buffer.

This fix also involves the removal of the PDF 1.4 'marking' devices.
The marking devices were used to actually implement the pixel marking.
The marking devices were created at the start of each high level drawing
operation and deleted after the completion of the operation.  The marking
device action has been merged into the primary PDF 1.4 compositing device.
This change eliminates some device creation overhead.  The overhead would
have been worse since most information about high level drawing operations
is not passed through the clist.  As a result it would have been necessary
to create marking devices for each low level operations.



The following issues are not included in this fix but need to be considered.

1)  The device filter logic is no longer used.  It may be desired to remove
this logic.

2)  We currently have a 'create_compositor' device proc.  However there
is not a 'delete_compositor' device proc.  As a result, compositor devices
can stay in the device chain even when they are no longer needed.  The
current fix turns the PDF 1.4 compositor into a 'forwarding' device.  This
is the same method used by the overprint compositor device.  I do not like
leaving these devices since there is some extra overhead and there may be
possible side effects.  (Testing has been done to try to find side effects
and none has been found with the current code.)

3)  This change only affects devices which can use the clist logic.  This
excludes the 'high' level devices.  These include the 'display', 'x11',
and 'pdfwrite' devices.  Thus these device will continue to use a full
image buffer.  It is possible to extend this fix to use a clist device
for the PDF 1.4 device for these devices.


Index: gdevbbox.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevbbox.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- gdevbbox.c	20 Sep 2004 06:48:29 -0000	1.22
+++ gdevbbox.c	14 Mar 2005 18:08:36 -0000	1.23
@@ -1166,7 +1166,7 @@
 private int
 bbox_create_compositor(gx_device * dev,
 		       gx_device ** pcdev, const gs_composite_t * pcte,
-		       const gs_imager_state * pis, gs_memory_t * memory)
+		       gs_imager_state * pis, gs_memory_t * memory)
 {
     gx_device_bbox *const bdev = (gx_device_bbox *) dev;
     gx_device *target = bdev->target;

Index: gdevdflt.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevdflt.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- gdevdflt.c	24 Jun 2004 05:03:36 -0000	1.24
+++ gdevdflt.c	14 Mar 2005 18:08:36 -0000	1.25
@@ -787,14 +787,14 @@
 int
 gx_no_create_compositor(gx_device * dev, gx_device ** pcdev,
 			const gs_composite_t * pcte,
-			const gs_imager_state * pis, gs_memory_t * memory)
+			gs_imager_state * pis, gs_memory_t * memory)
 {
     return_error(gs_error_unknownerror);	/* not implemented */
 }
 int
 gx_default_create_compositor(gx_device * dev, gx_device ** pcdev,
 			     const gs_composite_t * pcte,
-			     const gs_imager_state * pis, gs_memory_t * memory)
+			     gs_imager_state * pis, gs_memory_t * memory)
 {
     return pcte->type->procs.create_default_compositor
 	(pcte, pcdev, dev, pis, memory);
@@ -802,12 +802,33 @@
 int
 gx_null_create_compositor(gx_device * dev, gx_device ** pcdev,
 			  const gs_composite_t * pcte,
-			  const gs_imager_state * pis, gs_memory_t * memory)
+			  gs_imager_state * pis, gs_memory_t * memory)
 {
     *pcdev = dev;
     return 0;
 }
 
+/*
+ * Default handler for creating a compositor device when writing the clist. */
+int
+gx_default_composite_clist_write_update(const gs_composite_t *pcte, gx_device * dev,
+		gx_device ** pcdev, gs_imager_state * pis, gs_memory_t * mem)
+{
+    *pcdev = dev;		/* Do nothing -> return the same device */
+    return 0;
+}
+
+/*
+ * Default handler for updating the clist device when reading a compositing
+ * device.
+ */
+int
+gx_default_composite_clist_read_update(gs_composite_t *pxcte, gx_device * cdev,
+		gx_device * tdev, gs_imager_state * pis, gs_memory_t * mem)
+{
+    return 0;			/* Do nothing */
+}
+
 int
 gx_default_finish_copydevice(gx_device *dev, const gx_device *from_dev)
 {

Index: gdevmem.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevmem.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- gdevmem.c	26 May 2004 04:10:58 -0000	1.8
+++ gdevmem.c	14 Mar 2005 18:08:36 -0000	1.9
@@ -26,6 +26,7 @@
 #include "gxgetbit.h"
 #include "gxdevmem.h"		/* semi-public definitions */
 #include "gdevmem.h"		/* private definitions */
+#include "gstrans.h"
 
 /* Structure descriptor */
 public_st_device_memory();
@@ -246,19 +247,37 @@
  * compute the maximum height.
  */
 int
-gdev_mem_max_height(const gx_device_memory * dev, int width, ulong size)
+gdev_mem_max_height(const gx_device_memory * dev, int width, ulong size,
+		bool page_uses_transparency)
 {
-    ulong max_height = size /
-	(bitmap_raster(width * dev->color_info.depth) +
-	 sizeof(byte *) * max(dev->num_planes, 1));
-    int height = (int)min(max_height, max_int);
+    int height;
+    ulong max_height;
 
-    /*
-     * Because of alignment rounding, the just-computed height might
-     * be too large by a small amount.  Adjust it the easy way.
-     */
-    while (gdev_mem_data_size(dev, width, height) > size)
-	--height;
+    if (page_uses_transparency) {
+        /*
+         * If the device is using PDF 1.4 transparency then we will need to
+         * also allocate image buffers for doing the blending operations.
+         * We can only estimate the space requirements.  However since it
+	 * is only an estimate, we may exceed our desired buffer space while
+	 * processing the file.
+	 */
+        max_height = size / (bitmap_raster(width
+		* dev->color_info.depth + ESTIMATED_PDF14_ROW_SPACE(width))
+		+ sizeof(byte *) * max(dev->num_planes, 1));
+        height = (int)min(max_height, max_int);
+    } else {
+	/* For non PDF 1.4 transparency, we can do an exact calculation */
+        max_height = size /
+	    (bitmap_raster(width * dev->color_info.depth) +
+	     sizeof(byte *) * max(dev->num_planes, 1));
+        height = (int)min(max_height, max_int);
+        /*
+         * Because of alignment rounding, the just-computed height might
+         * be too large by a small amount.  Adjust it the easy way.
+         */
+        while (gdev_mem_data_size(dev, width, height) > size)
+	    --height;
+    }
     return height;
 }
 

Index: gdevnfwd.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevnfwd.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- gdevnfwd.c	28 Jan 2005 18:11:05 -0000	1.27
+++ gdevnfwd.c	14 Mar 2005 18:08:36 -0000	1.28
@@ -125,6 +125,16 @@
     set_dev_proc(dev, decode_color, gx_forward_decode_color);
 }
 
+int
+gx_forward_close_device(gx_device * dev)
+{
+    gx_device_forward * const fdev = (gx_device_forward *)dev;
+    gx_device *tdev = fdev->target;
+
+    return (tdev == 0) ? gx_default_close_device(dev)
+		       : dev_proc(tdev, close_device)(tdev);
+}
+
 void
 gx_forward_get_initial_matrix(gx_device * dev, gs_matrix * pmat)
 {
@@ -224,6 +234,20 @@
 }
 
 int
+gx_forward_copy_alpha(gx_device * dev, const byte * data, int data_x,
+	   int raster, gx_bitmap_id id, int x, int y, int width, int height,
+		      gx_color_index color, int depth)
+{
+    gx_device_forward * const fdev = (gx_device_forward *)dev;
+    gx_device *tdev = fdev->target;
+
+    if (tdev == 0)
+	return_error(gs_error_Fatal);
+    return dev_proc(tdev, copy_mono)
+	(tdev, data, data_x, raster, id, x, y, width, height, color, depth);
+}
+
+int
 gx_forward_copy_color(gx_device * dev, const byte * data,
 		      int dx, int raster, gx_bitmap_id id,
 		      int x, int y, int w, int h)

Index: gdevp14.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevp14.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- gdevp14.c	18 Aug 2004 04:48:56 -0000	1.26
+++ gdevp14.c	14 Mar 2005 18:08:36 -0000	1.27
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2001-2003 artofcode LLC.
+  Copyright (C) 2001-2004 artofcode LLC.
   
   This software is provided AS-IS with no warranty, either express or
   implied.
@@ -17,7 +17,7 @@
   Author: Raph Levien <raph at artofcode.com>
 */
 /* $Id$ */
-/* Device filter implementing PDF 1.4 imaging model */
[...2025 lines suppressed...]
+
+    /*
+     * We only handle the push/pop operations. Save and restore the color_info
+     * field for the clist device.  (This is needed since the process color
+     * model of the clist device needs to match the PDF 1.4 compositing
+     * device.
+     */
+    switch (pdf14pct->params.pdf14_op) {
+	case PDF14_PUSH_DEVICE:
+	    p14dev->saved_clist_color_info = cdev->color_info;
+	    cdev->color_info = p14dev->color_info;
+	    break;
+	case PDF14_POP_DEVICE:
+	    cdev->color_info = p14dev->saved_clist_color_info;
+	    break;
+	default:
+	    break;		/* do nothing for remaining ops */
+    }
     return 0;
 }

Index: gdevp14.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevp14.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- gdevp14.h	21 Feb 2002 22:24:51 -0000	1.3
+++ gdevp14.h	14 Mar 2005 18:08:36 -0000	1.4
@@ -20,7 +20,70 @@
 #ifndef gdevp14_INCLUDED
 #  define gdevp14_INCLUDED
 
-int
-gs_pdf14_device_filter(gs_device_filter_t **pdf, int depth, gs_memory_t *mem);
+typedef enum {
+    DeviceGray = 0,
+    DeviceRGB = 1,
+    DeviceCMYK = 2
+} pdf14_default_colorspace_t;
+
+typedef struct pdf14_buf_s pdf14_buf;
+typedef struct pdf14_ctx_s pdf14_ctx;
+
+struct pdf14_buf_s {
+    pdf14_buf *saved;
+
+    bool isolated;
+    bool knockout;
+    byte alpha;
+    byte shape;
+    gs_blend_mode_t blend_mode;
+
+    bool has_alpha_g;
+    bool has_shape;
+
+    gs_int_rect rect;
+    /* Note: the traditional GS name for rowstride is "raster" */
+
+    /* Data is stored in planar format. Order of planes is: pixel values,
+       alpha, shape if present, alpha_g if present. */
+
+    int rowstride;
+    int planestride;
+    int n_chan; /* number of pixel planes including alpha */
+    int n_planes; /* total number of planes including alpha, shape, alpha_g */
+    byte *data;
+
+    byte *transfer_fn;
+
+    gs_int_rect bbox;
+};
+
+struct pdf14_ctx_s {
+    pdf14_buf *stack;
+    pdf14_buf *maskbuf;
+    gs_memory_t *memory;
+    gs_int_rect rect;
+    bool additive;
+    int n_chan;
+};
+
+typedef struct pdf14_device_s {
+    gx_device_forward_common;
+
+    pdf14_ctx *ctx;
+    float opacity;
+    float shape;
+    float alpha; /* alpha = opacity * shape */
+    gs_blend_mode_t blend_mode;
+    const gx_color_map_procs *(*save_get_cmap_procs)(const gs_imager_state *,
+						     const gx_device *);
+    gx_device_color_info saved_clist_color_info;
+} pdf14_device;
+
+int gs_pdf14_device_push(gs_memory_t *mem, gs_imager_state * pis,
+		gx_device * * pdev, gx_device * target);
+
+int send_pdf14trans(gs_imager_state * pis, gx_device * dev,
+    gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem);
 
 #endif /* gdevp14_INCLUDED */

Index: gdevprn.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevprn.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- gdevprn.c	4 Aug 2004 19:36:12 -0000	1.18
+++ gdevprn.c	14 Mar 2005 18:08:36 -0000	1.19
@@ -25,6 +25,7 @@
 #include "gxclio.h"
 #include "gxgetbit.h"
 #include "gdevplnx.h"
+#include "gstrans.h"
 
 /*#define DEBUGGING_HACKS*/
 
@@ -144,7 +145,8 @@
 		      (ppdev->bandlist_memory == 0 ? pdev->memory->non_gc_memory:
 		       ppdev->bandlist_memory),
 		      ppdev->free_up_bandlist_memory,
-		      ppdev->clist_disable_mask);
+		      ppdev->clist_disable_mask,
+		      ppdev->page_uses_transparency);
     code = (*gs_clist_device_procs.open_device)( (gx_device *)pcldev );
     if (code < 0) {
 	/* If there wasn't enough room, and we haven't */
@@ -238,6 +240,7 @@
     ppdev->orig_procs = pdev->procs;
     for ( pass = 1; pass <= (reallocate ? 2 : 1); ++pass ) {
 	ulong mem_space;
+	ulong pdf14_trans_buffer_size = 0;
 	byte *base = 0;
 	bool bufferSpace_is_default = false;
 	gdev_prn_space_params space_params;
@@ -267,7 +270,11 @@
 	memset(ppdev->skip, 0, sizeof(ppdev->skip));
 	ppdev->printer_procs.buf_procs.size_buf_device
 	    (&buf_space, pdev, NULL, pdev->height, false);
-	mem_space = buf_space.bits + buf_space.line_ptrs;
+	if (ppdev->page_uses_transparency)
+	    pdf14_trans_buffer_size = new_height
+		* (ESTIMATED_PDF14_ROW_SPACE(new_width) >> 3);
+	mem_space = buf_space.bits + buf_space.line_ptrs
+		    + pdf14_trans_buffer_size;
 
 	/* Compute desired space params: never use the space_params as-is. */
 	/* Rather, give the dev-specific driver a chance to adjust them. */
@@ -483,6 +490,8 @@
 	(code = param_write_long(plist, "BandBufferSpace", &ppdev->space_params.band.BandBufferSpace)) < 0 ||
 	(code = param_write_bool(plist, "OpenOutputFile", &ppdev->OpenOutputFile)) < 0 ||
 	(code = param_write_bool(plist, "ReopenPerPage", &ppdev->ReopenPerPage)) < 0 ||
+	(code = param_write_bool(plist, "PageUsesTransparency",
+			 	&ppdev->page_uses_transparency)) < 0 ||
 	(ppdev->Duplex_set >= 0 &&
 	 (code = (ppdev->Duplex_set ?
 		  param_write_bool(plist, "Duplex", &ppdev->Duplex) :
@@ -518,6 +527,7 @@
     bool is_open = pdev->is_open;
     bool oof = ppdev->OpenOutputFile;
     bool rpp = ppdev->ReopenPerPage;
+    bool page_uses_transparency = ppdev->page_uses_transparency;
     bool duplex;
     int duplex_set = -1;
     int width = pdev->width;
@@ -547,6 +557,16 @@
 	    break;
     }
 
+    switch (code = param_read_bool(plist, (param_name = "PageUsesTransparency"),
+			    				&page_uses_transparency)) {
+	default:
+	    ecode = code;
+	    param_signal_error(plist, param_name, ecode);
+	case 0:
+	case 1:
+	    break;
+    }
+
     if (ppdev->Duplex_set >= 0)	/* i.e., Duplex is supported */
 	switch (code = param_read_bool(plist, (param_name = "Duplex"),
 				       &duplex)) {
@@ -646,6 +666,7 @@
 
     ppdev->OpenOutputFile = oof;
     ppdev->ReopenPerPage = rpp;
+    ppdev->page_uses_transparency = page_uses_transparency;
     if (duplex_set >= 0) {
 	ppdev->Duplex = duplex;
 	ppdev->Duplex_set = duplex_set;

Index: gdevprn.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevprn.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- gdevprn.h	11 Mar 2003 11:36:41 -0000	1.13
+++ gdevprn.h	14 Mar 2005 18:08:36 -0000	1.14
@@ -217,6 +217,7 @@
     long BufferSpace;		/* space to use for buffer */
     gx_band_params_t band;	/* see gxclist.h */
     bool params_are_read_only;	/* true if put_params may not modify this struct */
+    bool page_uses_transparency; /* PDF 1.4 transparency is used on the page */
     gdev_prn_banding_type banding_type;	/* used to force banding or bitmap */
 };
 
@@ -231,6 +232,7 @@
 		/* ------ Other device parameters ------ */\
 	bool OpenOutputFile;\
 	bool ReopenPerPage;\
+	bool page_uses_transparency;\
 	bool Duplex;\
 	  int Duplex_set;		/* -1 = not supported */\
 		/* ------ End of parameters ------ */\
@@ -381,6 +383,7 @@
 	 { 0 },		/* fname */\
 	0/*false*/,	/* OpenOutputFile */\
 	0/*false*/,	/* ReopenPerPage */\
+	0/*false*/,	/* page_uses_transparency */\
 	0/*false*/, -1,	/* Duplex[_set] */\
 	0/*false*/, 0, 0, 0, /* file_is_new ... buf */\
 	0, 0, 0, 0, 0/*false*/, 0, 0, /* buffer_memory ... clist_dis'_mask */\

Index: gdevpsdu.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevpsdu.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- gdevpsdu.c	31 Jan 2005 02:02:58 -0000	1.22
+++ gdevpsdu.c	14 Mar 2005 18:08:36 -0000	1.23
@@ -449,7 +449,7 @@
     gx_device *             dev,
     gx_device **            pcdev,
     const gs_composite_t *  pct,
-    const gs_imager_state * pis,
+    gs_imager_state * pis,
     gs_memory_t *           mem )
 {
     if (gs_is_overprint_compositor(pct)) {

Index: gsalphac.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gsalphac.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- gsalphac.c	4 Aug 2004 19:36:12 -0000	1.7
+++ gsalphac.c	14 Mar 2005 18:08:36 -0000	1.8
@@ -102,7 +102,9 @@
 	c_alpha_create_default_compositor,
 	c_alpha_equal,
 	c_alpha_write,
-	c_alpha_read
+	c_alpha_read,
+	gx_default_composite_clist_write_update,
+	gx_default_composite_clist_read_update
     }
 };
 typedef struct gs_composite_alpha_s {
@@ -262,8 +264,8 @@
 /* Create an alpha compositor. */
 private int
 c_alpha_create_default_compositor(const gs_composite_t * pcte,
-	   gx_device ** pcdev, gx_device * dev, const gs_imager_state * pis,
-				  gs_memory_t * mem)
+	   gx_device ** pcdev, gx_device * dev, gs_imager_state * pis,
+	   gs_memory_t * mem)
 {
     gx_device_composite_alpha *cdev;
 

Index: gsht.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gsht.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- gsht.c	4 Aug 2004 19:36:12 -0000	1.22
+++ gsht.c	14 Mar 2005 18:08:36 -0000	1.23
@@ -766,7 +766,13 @@
  *  num_comp    For the operand halftone, this is the number of halftone
  *              components included in the specification. For the device
  *              halftone in the imager state, this is always the same as
- *              the number of color model components.
+ *              the number of color model components (see num_dev_comp).
+ *
+ *  num_dev_comp The number of components in the device process color model
+ *		when the operand halftone was created.  With some compositor
+ *		devices (for example PDF 1.4) we can have differences in the
+ *		process color model of the compositor versus the output device.
+ *		These compositor devices do not halftone.
  *
  *  components  For the operand halftone, this field is non-null only if
  *              multiple halftones are provided. In that case, the size
@@ -951,7 +957,7 @@
     const gx_device *       dev )
 {
     gx_device_halftone      dht;
-    int                     num_comps = dev->color_info.num_components;
+    int                     num_comps = pdht->num_dev_comp;
     int                     i, code = 0;
     bool                    used_default = false;
     int                     lcm_width = 1, lcm_height = 1;
@@ -972,7 +978,7 @@
                           "gx_imager_dev_ht_install(components)" );
     if (dht.components == NULL)
 	return_error(gs_error_VMerror);
-    dht.num_comp = num_comps;
+    dht.num_comp = dht.num_dev_comp = num_comps;
     /* lcm_width, lcm_height are filled in later */
 
     /* initialize the components array */
@@ -1223,6 +1229,7 @@
     gs_halftone *new_ht;
     int code;
 
+    pdht->num_dev_comp = pgs->device->color_info.num_components;
     if (old_ht != 0 && old_ht->rc.memory == mem &&
 	old_ht->rc.ref_count == 1
 	)

Index: gsistate.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gsistate.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- gsistate.c	4 Aug 2004 19:36:12 -0000	1.10
+++ gsistate.c	14 Mar 2005 18:08:36 -0000	1.11
@@ -28,6 +28,7 @@
 #include "gxistate.h"
 #include "gzht.h"
 #include "gzline.h"
+#include "gxfmap.h"
 
 /******************************************************************************
  * See gsstate.c for a discussion of graphics/imager state memory management. *
@@ -124,7 +125,7 @@
 		      gx_transfer_map, &st_transfer_map,
 		      mem, return_error(gs_error_VMerror),
 		      "gs_imager_state_init(transfer)", 1);
-    pis->set_transfer.gray->proc = imager_null_transfer;
+    pis->set_transfer.gray->proc = gs_identity_transfer;
     pis->set_transfer.gray->id = gs_next_ids(pis->memory, 1);
     pis->set_transfer.gray->values[0] = frac_0;
     pis->set_transfer.red =

Index: gsovrc.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gsovrc.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- gsovrc.c	22 Sep 2004 00:37:12 -0000	1.8
+++ gsovrc.c	14 Mar 2005 18:08:36 -0000	1.9
@@ -209,7 +209,9 @@
         c_overprint_create_default_compositor,  /* procs.create_default_compositor */
         c_overprint_equal,                      /* procs.equal */
         c_overprint_write,                      /* procs.write */
-        c_overprint_read                        /* procs.read */
+        c_overprint_read,                       /* procs.read */
+	gx_default_composite_clist_write_update,/* procs.composite_clist_write_update */
+	gx_default_composite_clist_read_update	/* procs.composite_clist_reade_update */
     }                                           /* procs */
 };
 
@@ -790,7 +792,7 @@
     gx_device *             dev,
     gx_device **            pcdev,
     const gs_composite_t *  pct,
-    const gs_imager_state * pis,
+    gs_imager_state *	    pis,
     gs_memory_t *           memory )
 {
     if (pct->type != &gs_composite_overprint_type)
@@ -942,7 +944,7 @@
     const gs_composite_t *  pct,
     gx_device **            popdev,
     gx_device *             tdev,
-    const gs_imager_state * pis,
+    gs_imager_state *	    pis,
     gs_memory_t *           mem )
 {
     const gs_overprint_t *  ovrpct = (const gs_overprint_t *)pct;

Index: gsropc.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gsropc.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- gsropc.c	21 Feb 2002 22:24:52 -0000	1.4
+++ gsropc.c	14 Mar 2005 18:08:36 -0000	1.5
@@ -37,7 +37,9 @@
 	c_rop_create_default_compositor,
 	c_rop_equal,
 	c_rop_write,
-	c_rop_read
+	c_rop_read,
+	gx_default_composite_clist_write_update,
+	gx_default_composite_clist_read_update
     }
 };
 
@@ -158,8 +160,8 @@
 /* Create a RasterOp compositor. */
 int
 c_rop_create_default_compositor(const gs_composite_t * pcte,
-	   gx_device ** pcdev, gx_device * dev, const gs_imager_state * pis,
-				gs_memory_t * mem)
+	gx_device ** pcdev, gx_device * dev, gs_imager_state * pis,
+	gs_memory_t * mem)
 {
     gs_logical_operation_t log_op = prcte->params.log_op;
     const gx_device_color *texture = prcte->params.texture;

Index: gstparam.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gstparam.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- gstparam.h	16 Jun 2002 08:45:42 -0000	1.10
+++ gstparam.h	14 Mar 2005 18:08:36 -0000	1.11
@@ -75,6 +75,7 @@
 #  define gs_color_space_DEFINED
 typedef struct gs_color_space_s gs_color_space;
 #endif
+
 /* (Update gs_trans_group_params_init if these change.) */
 typedef struct gs_transparency_group_params_s {
     const gs_color_space *ColorSpace;
@@ -87,8 +88,11 @@
     TRANSPARENCY_MASK_Alpha,
     TRANSPARENCY_MASK_Luminosity
 } gs_transparency_mask_subtype_t;
+
 #define GS_TRANSPARENCY_MASK_SUBTYPE_NAMES\
   "Alpha", "Luminosity"
+
+/* See the gx_transparency_mask_params_t type below */
 /* (Update gs_trans_mask_params_init if these change.) */
 typedef struct gs_transparency_mask_params_s {
     gs_transparency_mask_subtype_t subtype;
@@ -98,6 +102,17 @@
     void *TransferFunction_data;
 } gs_transparency_mask_params_t;
 
+#define MASK_TRANSFER_FUNCTION_SIZE 256
+
+/* The post clist version of transparency mask parameters */
+typedef struct gx_transparency_mask_params_s {
+    gs_transparency_mask_subtype_t subtype;
+    bool has_Background;
+    bool function_is_identity;
+    float Background[GS_CLIENT_COLOR_MAX_COMPONENTS];
+    byte transfer_fn[MASK_TRANSFER_FUNCTION_SIZE];
+} gx_transparency_mask_params_t;
+
 /* Select the opacity or shape parameters. */
 typedef enum {
     TRANSPARENCY_CHANNEL_Opacity = 0,

Index: gstrans.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gstrans.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- gstrans.c	8 Sep 2003 13:30:02 -0000	1.18
+++ gstrans.c	14 Mar 2005 18:08:36 -0000	1.19
@@ -16,12 +16,15 @@
 
 /* $Id$ */
 /* Implementation of transparency, other than rendering */
+#include "math_.h"
+#include "memory_.h"
 #include "gx.h"
 #include "gserrors.h"
 #include "gstrans.h"
 #include "gsutil.h"
 #include "gzstate.h"
 #include "gxdevcli.h"
+#include "gdevp14.h"
 
 #define PUSH_TS 0
 
@@ -98,82 +101,6 @@
 
 /* ------ Transparency rendering stack ------ */
 
-/*
-  This area of the transparency facilities is in flux.  Here is a proposal
-  for extending the driver interface.  The material below will eventually
-  go in gxdevcli.h.
-*/
-
-/*
-  Push the current transparency state (*ppts) onto the associated stack,
-  and set *ppts to a new transparency state of the given dimension.  The
-  transparency state may copy some or all of the imager state, such as the
-  current alpha and/or transparency mask values, and definitely copies the
-  parameters.
-*/
-#define dev_t_proc_begin_transparency_group(proc, dev_t)\
-  int proc(gx_device *dev,\
-    const gs_transparency_group_params_t *ptgp,\
-    const gs_rect *pbbox,\
-    gs_imager_state *pis,\
-    gs_transparency_state_t **ppts,\
-    gs_memory_t *mem)
-#define dev_proc_begin_transparency_group(proc)\
-  dev_t_proc_begin_transparency_group(proc, gx_device)
-
-/*
-  End a transparency group: blend the top element of the transparency
-  stack, which must be a group, into the next-to-top element, popping the
-  stack.  If the stack only had a single element, blend into the device
-  output.  Set *ppts to 0 iff the stack is now empty.  If end_group fails,
-  the stack is *not* popped.
-*/
-#define dev_t_proc_end_transparency_group(proc, dev_t)\
-  int proc(gx_device *dev,\
-    gs_imager_state *pis,\
-    gs_transparency_state_t **ppts)
-#define dev_proc_end_transparency_group(proc)\
-  dev_t_proc_end_transparency_group(proc, gx_device)
-
-/*
-  Push the transparency state and prepare to render a transparency mask.
-  This is similar to begin_transparency_group except that it only
-  accumulates coverage values, not full pixel values.
-*/
-#define dev_t_proc_begin_transparency_mask(proc, dev_t)\
-  int proc(gx_device *dev,\
-    const gs_transparency_mask_params_t *ptmp,\
-    const gs_rect *pbbox,\
-    gs_imager_state *pis,\
-    gs_transparency_state_t **ppts,\
-    gs_memory_t *mem)
-#define dev_proc_begin_transparency_mask(proc)\
-  dev_t_proc_begin_transparency_mask(proc, gx_device)
-
-/*
-  Store a pointer to the rendered transparency mask into *pptm, popping the
-  stack like end_group.  Normally, the client will follow this by using
-  rc_assign to store the rendered mask into pis->{opacity,shape}.mask.  If
-  end_mask fails, the stack is *not* popped.
-*/
-#define dev_t_proc_end_transparency_mask(proc, dev_t)\
-  int proc(gx_device *dev,\
-    gs_transparency_mask_t **pptm)
-#define dev_proc_end_transparency_mask(proc)\
-  dev_t_proc_end_transparency_mask(proc, gx_device)
-
-/*
-  Pop the transparency stack, discarding the top element, which may be
-  either a group or a mask.  Set *ppts to 0 iff the stack is now empty.
-*/
-#define dev_t_proc_discard_transparency_layer(proc, dev_t)\
-  int proc(gx_device *dev,\
-    gs_transparency_state_t **ppts)
-#define dev_proc_discard_transparency_layer(proc)\
-  dev_t_proc_discard_transparency_layer(proc, gx_device)
-
-     /* (end of proposed driver interface extensions) */
-
 gs_transparency_state_type_t
 gs_current_transparency_type(const gs_state *pgs)
 {
@@ -213,6 +140,34 @@
 
 }
 
+/*
+ * Push a PDF 1.4 transparency compositor onto the current device. Note that
+ * if the current device already is a PDF 1.4 transparency compositor, the
+ * create_compositor will update its parameters but not create a new
+ * compositor device.
+ */
+private int
+gs_state_update_pdf14trans(gs_state * pgs, gs_pdf14trans_params_t * pparams)
+{
+    gs_imager_state * pis = (gs_imager_state *)pgs;
+    gx_device * dev = pgs->device;
+    gx_device * pdf14dev;
+    int code;
+
+    /*
+     * Send the PDF 1.4 create compositor action specified by the parameters.
+     */
+    code = send_pdf14trans(pis, dev, &pdf14dev, pparams, pgs->memory);
+    /*
+     * If we created a new PDF 1.4 compositor device then we need to install it
+     * into the graphics state.
+     */
+    if (code >= 0 && pdf14dev != dev)
+        gx_set_device_only(pgs, pdf14dev);
+
+    return code;
+}
+
 void
 gs_trans_group_params_init(gs_transparency_group_params_t *ptgp)
 {
@@ -226,6 +181,8 @@
 			    const gs_transparency_group_params_t *ptgp,
 			    const gs_rect *pbbox)
 {
+    gs_pdf14trans_params_t params = { 0 };
+
 #ifdef DEBUG
     if (gs_debug_c('v')) {
 	static const char *const cs_names[] = {
@@ -243,43 +200,91 @@
 		 ptgp->Isolated, ptgp->Knockout);
     }
 #endif
-    if (dev_proc(pgs->device, begin_transparency_group) != 0)
-	return (*dev_proc(pgs->device, begin_transparency_group)) (pgs->device, ptgp,
-								   pbbox, (gs_imager_state *)pgs,
-								   NULL, NULL);
+    /*
+     * Put parameters into a compositor parameter and then call the
+     * create_compositor.  This will pass the data to the PDF 1.4
+     * transparency device.
+     */
+    params.pdf14_op = PDF14_BEGIN_TRANS_GROUP;
+    params.Isolated = ptgp->Isolated;
+    params.Knockout = ptgp->Knockout;
+    params.opacity = pgs->opacity;
+    params.shape = pgs->shape;
+    params.blend_mode = pgs->blend_mode;
+    /*
+     * We are currently doing nothing with the colorspace.  Currently
+     * the blending colorspace is based upon the processs color model
+     * of the output device.
+     */
+    params.bbox = *pbbox;
+    return gs_state_update_pdf14trans(pgs, &params);
+}
+
+int
+gx_begin_transparency_group(gs_imager_state * pis, gx_device * pdev,
+				const gs_pdf14trans_params_t * pparams)
+{
+    gs_transparency_group_params_t tgp = {0};
+    gs_rect bbox;
+
+    tgp.Isolated = pparams->Isolated;
+    tgp.Knockout = pparams->Knockout;
+    pis->opacity.alpha = pparams->opacity.alpha;
+    pis->shape.alpha = pparams->shape.alpha;
+    pis->blend_mode = pparams->blend_mode;
+    bbox = pparams->bbox;
+#ifdef DEBUG
+    if (gs_debug_c('v')) {
+	static const char *const cs_names[] = {
+	    GS_COLOR_SPACE_TYPE_NAMES
+	};
+
+	dlprintf5("[v](0x%lx)begin_transparency_group [%g %g %g %g]\n",
+		  (ulong)pis, bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
+	if (tgp.ColorSpace)
+	    dprintf1("     CS = %s",
+		cs_names[(int)gs_color_space_get_index(tgp.ColorSpace)]);
+	else
+	    dputs("     (no CS)");
+	dprintf2("  Isolated = %d  Knockout = %d\n",
+		 tgp.Isolated, tgp.Knockout);
+    }
+#endif
+    if (dev_proc(pdev, begin_transparency_group) != 0)
+	return (*dev_proc(pdev, begin_transparency_group)) (pdev, &tgp,
+							&bbox, pis, NULL, NULL);
     else
 	return 0;
-#if PUSH_TS
-    return push_transparency_stack(pgs, TRANSPARENCY_STATE_Group,
-				   "gs_begin_transparency_group");
-#endif
 }
 
 int
 gs_end_transparency_group(gs_state *pgs)
 {
-    if (dev_proc(pgs->device, end_transparency_group) != 0)
-	return (*dev_proc(pgs->device, end_transparency_group)) (pgs->device, (gs_imager_state *)pgs,
-								 NULL);
+    gs_pdf14trans_params_t params = { 0 };
+
+    params.pdf14_op = PDF14_END_TRANS_GROUP;  /* Other parameters not used */
+    return gs_state_update_pdf14trans(pgs, &params);
+}
+
+int
+gx_end_transparency_group(gs_imager_state * pis, gx_device * pdev)
+{
+    if (dev_proc(pdev, end_transparency_group) != 0)
+	return (*dev_proc(pdev, end_transparency_group)) (pdev, pis, NULL);
     else
 	return 0;
-#if 0
-    gs_transparency_state_t *pts = pgs->transparency_stack;
-
-    if_debug1('v', "[v](0x%lx)end_transparency_group\n", (ulong)pgs);
-    if (!pts || pts->type != TRANSPARENCY_STATE_Group)
-	return_error(gs_error_rangecheck);
-    pop_transparency_stack(pgs, "gs_end_transparency_group");
-    return 0;
-#endif
 }
 
+/*
+ * Handler for identity mask transfer functions.
+ */
 private int
 mask_transfer_identity(floatp in, float *out, void *proc_data)
 {
-    *out = in;
+    *out = (float) in;
     return 0;
 }
+
 void
 gs_trans_mask_params_init(gs_transparency_mask_params_t *ptmp,
 			  gs_transparency_mask_subtype_t subtype)
@@ -291,10 +296,12 @@
 }
 
 int
-gs_begin_transparency_mask(gs_state *pgs,
-			   const gs_transparency_mask_params_t *ptmp,
-			   const gs_rect *pbbox)
+gs_begin_transparency_mask(gs_state * pgs,
+			   const gs_transparency_mask_params_t * ptmp,
+			   const gs_rect * pbbox)
 {
+    gs_pdf14trans_params_t params = { 0 };
+    int i;
 
     if_debug8('v', "[v](0x%lx)begin_transparency_mask [%g %g %g %g]\n\
       subtype = %d  has_Background = %d  %s\n",
@@ -302,42 +309,73 @@
 	      (int)ptmp->subtype, ptmp->has_Background,
 	      (ptmp->TransferFunction == mask_transfer_identity ? "no TR" :
 	       "has TR"));
-    if (dev_proc(pgs->device, begin_transparency_mask) != 0)
-	return (*dev_proc(pgs->device, begin_transparency_mask))
-	    (pgs->device, ptmp, pbbox, (gs_imager_state *)pgs, NULL, NULL);
+    params.pdf14_op = PDF14_BEGIN_TRANS_MASK;
+    params.bbox = *pbbox;
+    params.subtype = ptmp->subtype;
+    params.has_Background = ptmp->has_Background;
+    if (ptmp->has_Background)
+	memcpy(params.Background, ptmp->Background, size_of(ptmp->Background));
+    params.function_is_identity =
+	    (ptmp->TransferFunction == mask_transfer_identity);
+    /* Sample the transfer function */
+    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
+	float in = (float)(i * (1.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)));
+	float out;
+
+	ptmp->TransferFunction(in, &out, ptmp->TransferFunction_data);
+	params.transfer_fn[i] = (byte)floor((double)(out * 255 + 0.5));
+    }
+    return gs_state_update_pdf14trans(pgs, &params);
+}
+
+int
+gx_begin_transparency_mask(gs_imager_state * pis, gx_device * pdev,
+				const gs_pdf14trans_params_t * pparams)
+{
+    gx_transparency_mask_params_t tmp;
+
+    tmp.subtype = pparams->subtype;
+    tmp.has_Background = pparams->has_Background;
+    memcpy(tmp.Background, pparams->Background, size_of(tmp.Background));
+    tmp.function_is_identity = pparams->function_is_identity;
+    memcpy(tmp.transfer_fn, pparams->transfer_fn, size_of(tmp.transfer_fn));
+    if_debug8('v', "[v](0x%lx)begin_transparency_mask [%g %g %g %g]\n\
+      subtype = %d  has_Background = %d  %s\n",
+	      (ulong)pis, pparams->bbox.p.x, pparams->bbox.p.y,
+	      pparams->bbox.q.x, pparams->bbox.q.y,
+	      (int)tmp.subtype, tmp.has_Background,
+	      (tmp.function_is_identity ? "no TR" :
+	       "has TR"));
+    if (dev_proc(pdev, begin_transparency_mask) != 0)
+	return (*dev_proc(pdev, begin_transparency_mask))
+	    		(pdev, &tmp, &(pparams->bbox), pis, NULL, NULL);
     else
 	return 0;
-	     
-#if PUSH_TS
-    return push_transparency_stack(pgs, TRANSPARENCY_STATE_Mask,
-				   "gs_begin_transparency_group");
-#endif
 }
 
 int
 gs_end_transparency_mask(gs_state *pgs,
 			 gs_transparency_channel_selector_t csel)
 {
-#if 0
-    gs_transparency_state_t *pts = pgs->transparency_stack;
-#endif
+    gs_pdf14trans_params_t params = { 0 };
 
     if_debug2('v', "[v](0x%lx)end_transparency_mask(%d)\n", (ulong)pgs,
 	      (int)csel);
 
     /* todo: route csel */
 
-    if (dev_proc(pgs->device, end_transparency_mask) != 0)
-	return (*dev_proc(pgs->device, end_transparency_mask))
-	    (pgs->device, NULL);
+    params.pdf14_op = PDF14_END_TRANS_MASK;  /* Other parameters not used */
+    return gs_state_update_pdf14trans(pgs, &params);
+}
+
+int
+gx_end_transparency_mask(gs_imager_state * pis, gx_device * pdev,
+				const gs_pdf14trans_params_t * pparams)
+{
+    if (dev_proc(pdev, end_transparency_mask) != 0)
+	return (*dev_proc(pdev, end_transparency_mask)) (pdev, NULL);
     else
 	return 0;
-#if 0
-    if (!pts || pts->type != TRANSPARENCY_STATE_Mask)
-	return_error(gs_error_rangecheck);
-    pop_transparency_stack(pgs, "gs_end_transparency_mask");
-    return 0;
-#endif
 }
 
 int
@@ -357,17 +395,48 @@
 gs_init_transparency_mask(gs_state *pgs,
 			  gs_transparency_channel_selector_t csel)
 {
-    /****** NYI, DUMMY ******/
-    gs_transparency_source_t *ptm;
+    gs_pdf14trans_params_t params = { 0 };
 
     if_debug2('v', "[v](0x%lx)init_transparency_mask(%d)\n", (ulong)pgs,
 	      (int)csel);
-    switch (csel) {
-    case TRANSPARENCY_CHANNEL_Opacity: ptm = &pgs->opacity; break;
-    case TRANSPARENCY_CHANNEL_Shape: ptm = &pgs->shape; break;
+
+    params.pdf14_op = PDF14_INIT_TRANS_MASK;
+    params.csel = csel;
+    return gs_state_update_pdf14trans(pgs, &params);
+}
+
+int
+gx_init_transparency_mask(gs_imager_state * pis,
+				const gs_pdf14trans_params_t * pparams)
+{
+    gs_transparency_source_t *ptm;
+
+    if_debug2('v', "[v](0x%lx)init_transparency_mask(%d)\n", (ulong)pis,
+	      (int)pparams->csel);
+    switch (pparams->csel) {
+    case TRANSPARENCY_CHANNEL_Opacity: ptm = &pis->opacity; break;
+    case TRANSPARENCY_CHANNEL_Shape: ptm = &pis->shape; break;
     default: return_error(gs_error_rangecheck);
     }
     rc_decrement_only(ptm->mask, "gs_init_transparency_mask");
     ptm->mask = 0;
     return 0;
 }
+
+int
+gs_push_pdf14trans_device(gs_state * pgs)
+{
+    gs_pdf14trans_params_t params = { 0 };
+
+    params.pdf14_op = PDF14_PUSH_DEVICE;  /* Other parameters not used */
+    return gs_state_update_pdf14trans(pgs, &params);
+}
+
+int
+gs_pop_pdf14trans_device(gs_state * pgs)
+{
+    gs_pdf14trans_params_t params = { 0 };
+
+    params.pdf14_op = PDF14_POP_DEVICE;  /* Other parameters not used */
+    return gs_state_update_pdf14trans(pgs, &params);
+}

Index: gstrans.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gstrans.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- gstrans.h	16 Jun 2002 08:45:42 -0000	1.9
+++ gstrans.h	14 Mar 2005 18:08:36 -0000	1.10
@@ -21,6 +21,81 @@
 #  define gstrans_INCLUDED
 
 #include "gstparam.h"
+#include "gxcomp.h"
+
+/*
+ * Define the operations for the PDF 1.4 transparency compositor.
+ */
+typedef enum {
+    PDF14_PUSH_DEVICE,
+    PDF14_POP_DEVICE,
+    PDF14_BEGIN_TRANS_GROUP,
+    PDF14_END_TRANS_GROUP,
+    PDF14_INIT_TRANS_MASK,
+    PDF14_BEGIN_TRANS_MASK,
+    PDF14_END_TRANS_MASK,
+    PDF14_SET_BLEND_PARAMS
+} pdf14_compositor_operations;
+
+#define PDF14_OPCODE_NAMES \
+{\
+    "PDF14_PUSH_DEVICE      ",\
+    "PDF14_POP_DEVICE       ",\
+    "PDF14_BEGIN_TRANS_GROUP",\
+    "PDF14_END_TRANS_GROUP  ",\
+    "PDF14_INIT_TRANS_MASK  ",\
+    "PDF14_BEGIN_TRANS_MASK ",\
+    "PDF14_END_TRANS_MASK   ",\
+    "PDF14_SET_BLEND_PARAMS "\
+}
+
+/* Bit definitions for serializing PDF 1.4 parameters */
+#define PDF14_SET_BLEND_MODE    (1 << 0)
+#define PDF14_SET_TEXT_KNOCKOUT (1 << 1)
+#define PDF14_SET_SHAPE_ALPHA   (1 << 2)
+#define PDF14_SET_OPACITY_ALPHA (1 << 3)
+
+typedef struct gs_transparency_source_s {
+    float alpha;		/* constant alpha */
+    gs_transparency_mask_t *mask;
+} gs_transparency_source_t;
+
+struct gs_pdf14trans_params_s {
+    /* The type of trasnparency operation */
+    pdf14_compositor_operations pdf14_op;
+    /* Changed parameters flag */
+    int changed;
+    /* Parameters from the gs_transparency_group_params_t structure */
+    bool Isolated;
+    bool Knockout;
+    gs_rect bbox;
+    /*The transparency channel selector */
+    gs_transparency_channel_selector_t csel;
+    /* Parameters from the gx_transparency_mask_params_t structure */
+    gs_transparency_mask_subtype_t subtype;
+    bool has_Background;
+    bool function_is_identity;
+    float Background[GS_CLIENT_COLOR_MAX_COMPONENTS];
+    byte transfer_fn[MASK_TRANSFER_FUNCTION_SIZE];
+    /* Individual transparency parameters */
+    gs_blend_mode_t blend_mode;
+    bool text_knockout;
+    gs_transparency_source_t opacity;
+    gs_transparency_source_t shape;
+};
+
+typedef struct gs_pdf14trans_params_s gs_pdf14trans_params_t;
+
+/*
+ * The PDF 1.4 transparency compositor structure. This is exactly analogous to
+ * other compositor structures, consisting of a the compositor common elements
+ * and the PDF 1.4 transparency specific parameters.
+ */
+typedef struct gs_pdf14trans_s {
+    gs_composite_common;
+    gs_pdf14trans_params_t  params;
+} gs_pdf14trans_t;
+
 
 /* Access transparency-related graphics state elements. */
 int gs_setblendmode(gs_state *, gs_blend_mode_t);
@@ -44,9 +119,13 @@
  * We have to abbreviate the procedure name because procedure names are
  * only unique to 23 characters on VMS.
  */
+int gs_push_pdf14trans_device(gs_state * pgs);
+
+int gs_pop_pdf14trans_device(gs_state * pgs);
+
 void gs_trans_group_params_init(gs_transparency_group_params_t *ptgp);
 
-int gs_begin_transparency_group(gs_state *pgs,
+int gs_begin_transparency_group(gs_state * pgs,
 				const gs_transparency_group_params_t *ptgp,
 				const gs_rect *pbbox);
 
@@ -67,4 +146,52 @@
 
 int gs_discard_transparency_layer(gs_state *pgs);
 
+/*
+ * Imager level routines for the PDF 1.4 transparency operations.
+ */
+int gx_begin_transparency_group(gs_imager_state * pis, gx_device * pdev,
+				const gs_pdf14trans_params_t * pparams);
+
+int gx_end_transparency_group(gs_imager_state * pis, gx_device * pdev);
+
+int gx_init_transparency_mask(gs_imager_state * pis,
+				const gs_pdf14trans_params_t * pparams);
+
+int gx_begin_transparency_mask(gs_imager_state * pis, gx_device * pdev,
+				const gs_pdf14trans_params_t * pparams);
+
+int gx_end_transparency_mask(gs_imager_state * pis, gx_device * pdev,
+				const gs_pdf14trans_params_t * pparams);
+
+int gx_discard_transparency_layer(gs_imager_state *pis);
+
+/*
+ * Verify that a compositor data structure is for the PDF 1.4 compositor.
+ */
+int gs_is_pdf14trans_compositor(const gs_composite_t * pct);
+
+/*
+ * Estimate the amount of space that will be required by the PDF 1.4
+ * transparency buffers for doing the blending operations.  These buffers
+ * use 8 bits per component plus one or two 8 bit alpha component values.
+ * In theory there can be a large number of these buffers required.  However
+ * we do not know the required number of buffers, the required numbe of
+ * alpha chanels, or the number of components for the blending operations.
+ * (This information is determined later as the data streams are parsed.)
+ * For now we are simply assuming that we will have three buffers with five
+ * eight bit values.  This is a hack but not too unreasonable.  However
+ * since it is a hack, we may exceed our desired buffer space while
+ * processing the file.
+ */
+#define NUM_PDF14_BUFFERS 3
+#define NUM_ALPHA_CHANNELS 1
+#define NUM_COLOR_CHANNELS 4
+#define BITS_PER_CHANNEL 8
+/* The estimated size of an individual PDF 1.4 buffer row (in bits) */
+#define ESTIMATED_PDF14_ROW_SIZE(width) ((width) * BITS_PER_CHANNEL\
+	* (NUM_ALPHA_CHANNELS + NUM_COLOR_CHANNELS))
+/* The estimated size of one row in all PDF 1.4 buffers (in bits) */
+#define ESTIMATED_PDF14_ROW_SPACE(width) \
+	(NUM_PDF14_BUFFERS * ESTIMATED_PDF14_ROW_SIZE(width))
+
 #endif /* gstrans_INCLUDED */

Index: gxband.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxband.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- gxband.h	21 Feb 2002 22:24:52 -0000	1.4
+++ gxband.h	14 Mar 2005 18:08:36 -0000	1.5
@@ -26,6 +26,7 @@
  * Define the parameters controlling banding.
  */
 typedef struct gx_band_params_s {
+    bool page_uses_transparency; /* PDF 1.4 transparency is used on the page */
     int BandWidth;		/* (optional) band width in pixels */
     int BandHeight;		/* (optional) */
     long BandBufferSpace;	/* (optional) */

Index: gxcldev.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxcldev.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- gxcldev.h	8 Sep 2003 12:06:56 -0000	1.13
+++ gxcldev.h	14 Mar 2005 18:08:36 -0000	1.14
@@ -709,6 +709,11 @@
 /* ------ Exported by gxclimag.c ------ */
 
 /*
+ * Write out any necessary color mapping data.
+ */
+int cmd_put_color_mapping(gx_device_clist_writer * cldev,
+				  const gs_imager_state * pis);
+/*
  * Add commands to represent a full (device) halftone.
  * (This routine should probably be in some other module.)
  */

Index: gxclimag.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxclimag.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- gxclimag.c	7 Oct 2004 05:18:34 -0000	1.11
+++ gxclimag.c	14 Mar 2005 18:08:36 -0000	1.12
@@ -47,8 +47,6 @@
 /* Forward references */
 private int cmd_put_set_data_x(gx_device_clist_writer * cldev,
 			       gx_clist_state * pcls, int data_x);
-private int cmd_put_color_mapping(gx_device_clist_writer * cldev,
-				  const gs_imager_state * pis);
 private bool check_rect_for_trivial_clip(
     const gx_clip_path *pcpath,  /* May be NULL, clip to evaluate */
     int px, int py, int qx, int qy  /* corners of box to test */
@@ -640,8 +638,10 @@
 		pie->color_map_is_known = true;
 		if (code >= 0) {
 		    uint want_known = ctm_known | clip_path_known |
-			(pie->color_space.id == gs_no_id ? 0 :
-			 color_space_known);
+				op_bm_tk_known | opacity_alpha_known |
+				shape_alpha_known | alpha_known |
+				(pie->color_space.id == gs_no_id ? 0 :
+							 color_space_known);
 
 		    code = cmd_do_write_unknown(cdev, pcls, want_known);
 		}
@@ -792,20 +792,23 @@
 int
 clist_create_compositor(gx_device * dev,
 			gx_device ** pcdev, const gs_composite_t * pcte,
-			const gs_imager_state * pis, gs_memory_t * mem)
+			gs_imager_state * pis, gs_memory_t * mem)
 {
-    byte *                  dp;
-    uint                    size = 0;
-    int                     code = pcte->type->procs.write(pcte, 0, &size);
-
-    /* always return the same device */
-    *pcdev = dev;
+    byte * dp;
+    uint size = 0;
+    int code = pcte->type->procs.write(pcte, 0, &size);
 
     /* determine the amount of space required */
     if (code < 0 && code != gs_error_rangecheck)
         return code;
     size += 2 + 1;      /* 2 bytes for the command code, one for the id */
 
+    /* Create a compositor device for clist writing (if needed) */
+    code = pcte->type->procs.clist_compositor_write_update(pcte, dev,
+		    					pcdev, pis, mem);
+    if (code < 0)
+        return code;
+
     /* overprint applies to all bands */
     code = set_cmd_put_all_op( dp,
                                (gx_device_clist_writer *)dev,
@@ -968,7 +971,7 @@
 }
 
 /* Write out any necessary color mapping data. */
-private int
+int
 cmd_put_color_mapping(gx_device_clist_writer * cldev,
 		      const gs_imager_state * pis)
 {
@@ -1287,7 +1290,34 @@
     }
     if (cmd_check_clip_path(cdev, pie->pcpath))
 	unknown |= clip_path_known;
-
+    /*
+     * Note: overprint and overprint_mode are implemented via a compositor
+     * device, which is passed separately through the command list. Hence,
+     * though both parameters are passed in the state as well, this usually
+     * has no effect.
+     */
+    if (cdev->imager_state.overprint != pis->overprint ||
+        cdev->imager_state.overprint_mode != pis->overprint_mode ||
+        cdev->imager_state.blend_mode != pis->blend_mode ||
+        cdev->imager_state.text_knockout != pis->text_knockout) {
+	unknown |= op_bm_tk_known;
+        cdev->imager_state.overprint = pis->overprint;
+        cdev->imager_state.overprint_mode = pis->overprint_mode;
+        cdev->imager_state.blend_mode = pis->blend_mode;
+        cdev->imager_state.text_knockout = pis->text_knockout;
+    }
+    if (cdev->imager_state.opacity.alpha != pis->opacity.alpha) {
+	unknown |= opacity_alpha_known;
+        cdev->imager_state.opacity.alpha = pis->opacity.alpha;
+    }
+    if (cdev->imager_state.shape.alpha != pis->shape.alpha) {
+	unknown |= shape_alpha_known;
+        cdev->imager_state.shape.alpha = pis->shape.alpha;
+    }
+    if (cdev->imager_state.alpha != pis->alpha) {
+	unknown |= alpha_known;
+        cdev->imager_state.alpha = pis->alpha;
+    }
     return unknown;
 }
 

Index: gxclist.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxclist.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- gxclist.c	24 Jun 2004 05:03:36 -0000	1.14
+++ gxclist.c	14 Mar 2005 18:08:36 -0000	1.15
@@ -291,6 +291,7 @@
 	(cdev->band_params.BandWidth ? cdev->band_params.BandWidth :
 	 target->width);
     int band_height = cdev->band_params.BandHeight;
+    bool page_uses_transparency = cdev->page_uses_transparency;
     const uint band_space =
     cdev->page_info.band_params.BandBufferSpace =
 	(cdev->band_params.BandBufferSpace ?
@@ -327,7 +328,7 @@
 	bits_size = clist_tile_cache_size(target, band_space);
 	bits_size = min(bits_size, data_size >> 1);
 	band_height = gdev_mem_max_height(&bdev, band_width,
-					  band_space - bits_size);
+			  band_space - bits_size, page_uses_transparency);
 	if (band_height == 0)
 	    return_error(gs_error_rangecheck);
     }

Index: gxclist.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxclist.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- gxclist.h	13 Sep 2002 22:21:22 -0000	1.6
+++ gxclist.h	14 Mar 2005 18:08:36 -0000	1.7
@@ -166,6 +166,7 @@
 	uint data_size;			/* size of buffer */\
 	gx_band_params_t band_params;	/* band buffering parameters */\
 	bool do_not_open_or_close_bandfiles;	/* if true, do not open/close bandfiles */\
+	bool page_uses_transparency;	/* if true then page uses PDF 1.4 transparency */\
 		/* Following are used for both writing and reading. */\
 	gx_bits_cache_chunk chunk;	/* the only chunk of bits */\
 	gx_bits_cache bits;\
@@ -280,7 +281,7 @@
   (st_device_forward_max_ptrs + st_imager_state_num_ptrs + 1)
 
 /* setup before opening clist device */
-#define clist_init_params(xclist, xdata, xdata_size, xtarget, xbuf_procs, xband_params, xexternal, xmemory, xfree_bandlist, xdisable)\
+#define clist_init_params(xclist, xdata, xdata_size, xtarget, xbuf_procs, xband_params, xexternal, xmemory, xfree_bandlist, xdisable, pageusestransparency)\
     BEGIN\
 	(xclist)->common.data = (xdata);\
 	(xclist)->common.data_size = (xdata_size);\
@@ -291,6 +292,7 @@
 	(xclist)->common.bandlist_memory = (xmemory);\
 	(xclist)->writer.free_up_bandlist_memory = (xfree_bandlist);\
 	(xclist)->writer.disable_mask = (xdisable);\
+	(xclist)->writer.page_uses_transparency = (pageusestransparency);\
     END
 
 /* Determine whether this clist device is able to recover VMerrors */

Index: gxclrast.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxclrast.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- gxclrast.c	28 Jan 2005 18:51:32 -0000	1.32
+++ gxclrast.c	14 Mar 2005 18:08:36 -0000	1.33
@@ -85,6 +85,7 @@
     if ( *p < 0x80 ) var = *p++;\
     else { const byte *_cbp; var = cmd_get_w(p, &_cbp); p = _cbp; }\
   END
+
 private long
 cmd_get_w(const byte * p, const byte ** rp)
 {
@@ -243,11 +244,10 @@
 #define data_bits_size cbuf_size
     byte *data_bits = 0;
     register const byte *cbp;
-    int dev_depth = cdev->color_info.depth;
-    int dev_depth_bytes = (dev_depth + 7) >> 3;
-    int odd_delta_shift = (dev_depth_bytes - 3) * 8;
+    int dev_depth;		/* May vary due to compositing devices */
+    int dev_depth_bytes;
+    int odd_delta_shift;
     int num_zero_bytes;
-    gx_color_index delta_offset = cmd_delta_offsets[dev_depth_bytes];
     gx_device *tdev;
     gx_clist_state state;
     gx_color_index *set_colors;
@@ -553,6 +553,8 @@
 			    gx_color_index delta = 0;
 			    uint data;
 
+			    dev_depth = cdev->color_info.depth;
+			    dev_depth_bytes = (dev_depth + 7) >> 3;
 		            switch (dev_depth_bytes) {
 				/* For cases with an even number of bytes */
 			        case 8:
@@ -583,13 +585,14 @@
 				        ((data & 0xf0) << 4) + (data & 0x0f));
 			        case 3:
 			            data = *cbp++;
+				    odd_delta_shift = (dev_depth_bytes - 3) * 8;
 			            delta |= ((gx_color_index)
 				        ((data & 0xe0) << 3) + (data & 0x1f)) << odd_delta_shift;
 				    data = *cbp++;
 			            delta |= ((gx_color_index) ((data & 0xf8) << 2) + (data & 0x07))
 				    			<< (odd_delta_shift + 11);
 		            }
-		            *pcolor += delta - delta_offset;;
+		            *pcolor += delta - cmd_delta_offsets[dev_depth_bytes];
 			}
 			if_debug1('L', " 0x%lx\n", *pcolor);
 			continue;
@@ -625,6 +628,8 @@
 		else {
 		    gx_color_index color = 0;
 
+		    dev_depth = cdev->color_info.depth;
+		    dev_depth_bytes = (dev_depth + 7) >> 3;
 		    switch (dev_depth_bytes - num_zero_bytes) {
 			case 8:
 			    color = (gx_color_index) * cbp++;
@@ -686,8 +691,8 @@
 		if (state.color_is_alpha) {
 		    if (!(op & 8))
 			depth = *cbp++;
-		} else
-		    depth = dev_depth;
+		} else 
+		    depth = cdev->color_info.depth;
 	      copy:cmd_getw(state.rect.x, cbp);
 		cmd_getw(state.rect.y, cbp);
 		if (op & 8) {	/* Use the current "tile". */
@@ -1199,6 +1204,12 @@
 				break;
 			    case cmd_opv_ext_create_compositor:
 				cbuf.ptr = cbp;
+				/*
+				 * The screen phase may have been changed during
+				 * the processing of masked images.
+				 */
+				gx_imager_setscreenphase(&imager_state,
+					    -x0, -y0, gs_color_select_all);
 				code = read_create_compositor(&cbuf, &imager_state,
 							      cdev, mem, &target);
 				cbp = cbuf.ptr;
@@ -2088,6 +2099,13 @@
         rc_increment(tdev);
         *ptarget = tdev;
     }
+
+    /* Perform any updates for the clist device required */
+    code = pcomp->type->procs.clist_compositor_read_update(pcomp,
+		    			(gx_device *)cdev, tdev, pis, mem);
+    if (code < 0)
+        return code;
+
     /* free the compositor object */
     if (pcomp != 0)
         gs_free_object(mem, pcomp, "read_create_compositor");

Index: gxclutil.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxclutil.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- gxclutil.c	5 Aug 2004 17:02:36 -0000	1.11
+++ gxclutil.c	14 Mar 2005 18:08:36 -0000	1.12
@@ -277,7 +277,7 @@
 {
     if_debug3('L', "[L]band %d: size=%u, left=%u",
 	      (int)(pcls - cldev->states),
-	      size, (uint) (cldev->cend - cldev->cnext));
+	      size, 0);
     return cmd_put_list_op(cldev, &pcls->list, size);
 }
 #endif
@@ -288,8 +288,7 @@
 		 uint size)
 {
     if_debug4('L', "[L]band range(%d,%d): size=%u, left=%u",
-	      band_min, band_max, size,
-	      (uint)(cldev->cend - cldev->cnext));
+	      band_min, band_max, size, 0);
     if (cldev->ccl != 0 && 
 	(cldev->ccl != &cldev->band_range_list ||
 	 band_min != cldev->band_range_min ||

Index: gxcmap.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxcmap.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- gxcmap.c	1 Oct 2004 23:35:02 -0000	1.23
+++ gxcmap.c	14 Mar 2005 18:08:36 -0000	1.24
@@ -1342,6 +1342,22 @@
     return 0;
 }
 
+gx_color_index
+gx_default_8bit_map_gray_color(gx_device * dev, const gx_color_value cv[])
+{
+    gx_color_index color = gx_color_value_to_byte(cv[0]);
+
+    return (color == gx_no_color_index ? color ^ 1 : color);
+}
+
+int
+gx_default_8bit_map_color_gray(gx_device * dev, gx_color_index color,
+			      gx_color_value pgray[1])
+{
+    pgray[0] = (gx_color_value)(color * gx_max_color_value / 255);
+    return 0;
+}
+
 /* RGB mapping for 24-bit true (RGB) color devices */
 
 gx_color_index

Index: gxcomp.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxcomp.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- gxcomp.h	22 Aug 2002 07:12:29 -0000	1.6
+++ gxcomp.h	14 Mar 2005 18:08:36 -0000	1.7
@@ -45,8 +45,9 @@
  * The following list is intended to enumerate all compositors. We
  * use definitions rather than an encoding to ensure a one-byte size.
  */
-#define GX_COMPOSITOR_ALPHA      0x01   /* DPS/Next alpha compositor */
-#define GX_COMPOSITOR_OVERPRINT  0x02   /* overprint/overprintmode compositor */
+#define GX_COMPOSITOR_ALPHA        0x01   /* DPS/Next alpha compositor */
+#define GX_COMPOSITOR_OVERPRINT    0x02   /* overprint/overprintmode compositor */
+#define GX_COMPOSITOR_PDF14_TRANS  0x03   /* PDF 1.4 transparency compositor */
 
 
 /*
@@ -73,7 +74,7 @@
      */
 #define composite_create_default_compositor_proc(proc)\
   int proc(const gs_composite_t *pcte, gx_device **pcdev,\
-    gx_device *dev, const gs_imager_state *pis, gs_memory_t *mem)
+    gx_device *dev, gs_imager_state *pis, gs_memory_t *mem)
     composite_create_default_compositor_proc((*create_default_compositor));
 
     /*
@@ -106,13 +107,42 @@
     gs_memory_t *mem)
     composite_read_proc((*read));
 
+    /*
+     * Update the clist write device when a compositor device is created.
+     */
+#define composite_clist_write_update(proc)\
+  int proc(const gs_composite_t * pcte, gx_device * dev, gx_device ** pcdev,\
+			gs_imager_state * pis, gs_memory_t * mem)
+    composite_clist_write_update((*clist_compositor_write_update));
+
+    /*
+     * Update the clist read device when a compositor device is created.
+     */
+#define composite_clist_read_update(proc)\
+  int proc(gs_composite_t * pcte, gx_device * cdev, gx_device * tdev,\
+			gs_imager_state * pis, gs_memory_t * mem)
+    composite_clist_read_update((*clist_compositor_read_update));
+
 } gs_composite_type_procs_t;
+
 typedef struct gs_composite_type_s {
     byte comp_id;   /* to identify compositor passed through command list */
     gs_composite_type_procs_t procs;
 } gs_composite_type_t;
 
 /*
+ * Default implementation for creating a compositor for clist writing.
+ * The default does nothing.
+ */
+composite_clist_write_update(gx_default_composite_clist_write_update);
+
+/*
+ * Default implementation for adjusting the clist reader when a compositor
+ * device is added.  The default does nothing.
+ */
+composite_clist_read_update(gx_default_composite_clist_read_update);
+
+/*
  * Compositing objects are reference-counted, because graphics states will
  * eventually reference them.  Note that the common part has no
  * garbage-collectible pointers and is never actually instantiated, so no

Index: gxdevcli.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxdevcli.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- gxdevcli.h	28 Jan 2005 19:11:07 -0000	1.35
+++ gxdevcli.h	14 Mar 2005 18:08:36 -0000	1.36
@@ -1080,7 +1080,7 @@
 #define dev_t_proc_create_compositor(proc, dev_t)\
   int proc(dev_t *dev,\
     gx_device **pcdev, const gs_composite_t *pcte,\
-    const gs_imager_state *pis, gs_memory_t *memory)
+    gs_imager_state *pis, gs_memory_t *memory)
 #define dev_proc_create_compositor(proc)\
   dev_t_proc_create_compositor(proc, gx_device)\
 
@@ -1148,7 +1148,7 @@
 */
 #define dev_t_proc_begin_transparency_mask(proc, dev_t)\
   int proc(gx_device *dev,\
-    const gs_transparency_mask_params_t *ptmp,\
+    const gx_transparency_mask_params_t *ptmp,\
     const gs_rect *pbbox,\
     gs_imager_state *pis,\
     gs_transparency_state_t **ppts,\

Index: gxdevice.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxdevice.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- gxdevice.h	30 Sep 2004 06:37:01 -0000	1.20
+++ gxdevice.h	14 Mar 2005 18:08:36 -0000	1.21
@@ -299,8 +299,11 @@
 dev_proc_map_cmyk_color(cmyk_8bit_map_cmyk_color);
 dev_proc_map_color_rgb(cmyk_8bit_map_color_rgb);
 dev_proc_decode_color(cmyk_8bit_map_color_cmyk);
+dev_proc_encode_color(gx_default_8bit_map_gray_color);
+dev_proc_decode_color(gx_default_8bit_map_color_gray);
 
 /* Default implementations for forwarding devices */
+dev_proc_close_device(gx_forward_close_device);
 dev_proc_get_initial_matrix(gx_forward_get_initial_matrix);
 dev_proc_sync_output(gx_forward_sync_output);
 dev_proc_output_page(gx_forward_output_page);

Index: gxdevmem.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxdevmem.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- gxdevmem.h	22 Aug 2002 07:12:29 -0000	1.6
+++ gxdevmem.h	14 Mar 2005 18:08:36 -0000	1.7
@@ -196,7 +196,8 @@
  * Do the inverse computation: given the device width and a buffer size,
  * compute the maximum height.
  */
-int gdev_mem_max_height(const gx_device_memory *, int, ulong);
+int gdev_mem_max_height(const gx_device_memory * dev, int width, ulong size,
+		bool page_uses_transparency);
 
 /*
  * Compute the standard raster (data bytes per line) similarly.

Index: gxdht.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxdht.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- gxdht.h	22 Aug 2002 07:12:29 -0000	1.8
+++ gxdht.h	14 Mar 2005 18:08:37 -0000	1.9
@@ -293,7 +293,9 @@
 #endif
 
 /*
- * Device Halftone Structure definition
+ * Device Halftone Structure definition.  See comments before
+ * gx_imager_dev_ht_install() for more information on this structure and its
+ * fields.
  */
 struct gx_device_halftone_s {
     gx_ht_order order;		/* must be first, for subclassing */
@@ -306,7 +308,8 @@
     gs_halftone_type type;
     gx_ht_order_component *components;
 
-    uint num_comp;
+    uint num_comp;		/* Number of components in the halftone */
+    uint num_dev_comp;		/* Number of process color model components */
     /* The following are computed from the above. */
     int lcm_width, lcm_height;	/* LCM of primary color tile sizes, */
     /* max_int if overflowed */

Index: gxdhtserial.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxdhtserial.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- gxdhtserial.c	8 Dec 2004 21:35:13 -0000	1.7
+++ gxdhtserial.c	14 Mar 2005 18:08:37 -0000	1.8
@@ -467,10 +467,10 @@
     byte *                      data,
     uint *                      psize )
 {
-    int                         num_comps = dev->color_info.num_components;
+    int                         num_dev_comps = pdht->num_dev_comp;
     int                         i, code;
-    uint                        req_size = 1, used_size = 1;
-                                /* 1 for halftone type */
+    uint                        req_size = 2, used_size = 2;
+                                /* 1 for halftone type, 1 for num_dev_comps */
 
     /*
      * With the introduction of color models, there should never be a
@@ -489,29 +489,25 @@
      *
      *  rc, id      Recreated by the allocation code on the renderer.
      *
-     *  num_comp    Must be the same as dev->color_info.num_components,
-     *              which must be the same on both the writer and the
-     *              rendered. Indeed, the entire color model must be the
-     *              same for writer and renderer.
-     *
      *  lcm_width,  Can be recreated by the de-serialization code on the
      *  lcm_height  the renderer. Since halftones are transmitted
      *              infrequently (for normal jobs), the time required
      *              for re-calculation is not significant.
      *
-     * Hence, the only fields that must be serialized are the type and
-     * the components.
+     * Hence, the only fields that must be serialized are the type,and
+     * the number of components.  (The number of components for the halftone
+     * may not match the device's if we are compositing with a process color
+     * model which does not match the output device.
      *
      * Several halftone components may be identical, but there is
      * currently no simple way to determine this. Halftones are normally
      * transmitted only once per page, so it is not clear that use of
      * such information would significantly reduce command list size.
      */
-    assert(pdht->num_comp == num_comps);
 
     /* calculate the required data space */
     for ( i = 0, code = gs_error_rangecheck;
-          i < num_comps && code == gs_error_rangecheck;
+          i < num_dev_comps && code == gs_error_rangecheck;
           i++) {
         uint     tmp_size = 0;
 
@@ -533,9 +529,11 @@
 
     /* the halftone type is known to fit in a byte */
     *data++ = (byte)pdht->type;
+    /* the number of components is known to fit in a byte */
+    *data++ = (byte)num_dev_comps;
 
     /* serialize the halftone components */
-    for (i = 0, code = 0; i < num_comps && code == 0; i++) {
+    for (i = 0, code = 0; i < num_dev_comps && code == 0; i++) {
         uint    tmp_size = req_size - used_size;
 
         code = gx_ht_write_component( &pdht->components[i],
@@ -579,7 +577,7 @@
     gx_ht_order_component   components[GX_DEVICE_COLOR_MAX_COMPONENTS];
     const byte *            data0 = data;
     gx_device_halftone      dht;
-    int                     num_comps = dev->color_info.num_components;
+    int                     num_dev_comps;
     int                     i, code;
 
     /* fill in some fixed fields */
@@ -587,7 +585,6 @@
     memset(&dht.rc, 0, sizeof(dht.rc));
     dht.id = gs_no_id;      /* updated during installation */
     dht.components = components;
-    dht.num_comp = num_comps;
     dht.lcm_width = 1;      /* recalculated during installation */
     dht.lcm_height = 1;
 
@@ -598,9 +595,10 @@
     if (size-- < 1)
         return_error(gs_error_rangecheck);
     dht.type = (gs_halftone_type)(*data++);
+    num_dev_comps = dht.num_dev_comp = dht.num_comp = *data++;
 
     /* process the component orders */
-    for (i = 0, code = 0; i < num_comps && code >= 0; i++) {
+    for (i = 0, code = 0; i < num_dev_comps && code >= 0; i++) {
         components[i].comp_number = i;
         code = gx_ht_read_component(&components[i], data, size, mem);
         if (code >= 0) {
@@ -619,7 +617,7 @@
      * array is on the stack rather than in the heap.
      */
     if (code < 0) {
-        for (i = 0; i < num_comps; i++)
+        for (i = 0; i < num_dev_comps; i++)
             gx_ht_order_release(&components[i].corder, mem, false);
     }
 

Index: gxistate.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxistate.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- gxistate.h	13 Mar 2004 18:28:52 -0000	1.21
+++ gxistate.h	14 Mar 2005 18:08:37 -0000	1.22
@@ -31,6 +31,7 @@
 #include "gxmatrix.h"
 #include "gxtmap.h"
 #include "gscspace.h"
+#include "gstrans.h"
 
 /*
   Define the subset of the PostScript graphics state that the imager library
@@ -196,10 +197,6 @@
 
 
 /* Define the imager state structure itself. */
-typedef struct gs_transparency_source_s {
-    float alpha;		/* constant alpha */
-    gs_transparency_mask_t *mask;
-} gs_transparency_source_t;
 /*
  * Note that the ctm member is a gs_matrix_fixed.  As such, it cannot be
  * used directly as the argument for procedures like gs_point_transform.

Index: lib.mak
===================================================================
RCS file: /cvs/ghostscript/gs/src/lib.mak,v
retrieving revision 1.205
retrieving revision 1.206
diff -u -d -r1.205 -r1.206
--- lib.mak	31 Jan 2005 03:08:44 -0000	1.205
+++ lib.mak	14 Mar 2005 18:08:37 -0000	1.206
@@ -901,7 +901,7 @@
 ### Memory devices
 
 $(GLOBJ)gdevmem.$(OBJ) : $(GLSRC)gdevmem.c $(GXERR) $(memory__h)\
- $(gsrect_h) $(gsstruct_h)\
+ $(gsrect_h) $(gsstruct_h) $(gstrans_h)\
  $(gxarith_h) $(gxgetbit_h) $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h)
 	$(GLCC) $(GLO_)gdevmem.$(OBJ) $(C_) $(GLSRC)gdevmem.c
 
@@ -1117,6 +1117,7 @@
 	$(ADDMOD) $(GLD)libs $(LIB12s)
 	$(ADDMOD) $(GLD)libs $(LIB13s)
 	$(ADDCOMP) $(GLD)libs overprint
+	$(ADDCOMP) $(GLD)libs pdf14trans
 	$(ADDMOD) $(GLD)libs -init gshtscr
 	$(ADDMOD) $(GLD)libs -include $(GLD)gsiodevs
 
@@ -1511,7 +1512,7 @@
 
 $(GLOBJ)gdevprn.$(OBJ) : $(GLSRC)gdevprn.c $(ctype__h)\
  $(gdevprn_h) $(gp_h) $(gsdevice_h) $(gsfname_h) $(gsparam_h)\
- $(gxclio_h) $(gxgetbit_h) $(gdevplnx_h)
+ $(gxclio_h) $(gxgetbit_h) $(gdevplnx_h) $(gstrans_h)
 	$(GLCC) $(GLO_)gdevprn.$(OBJ) $(C_) $(GLSRC)gdevprn.c
 
 # Planar page devices
@@ -2448,13 +2449,14 @@
 
 # ---------------- Transparency ---------------- #
 
-gstrans_h=$(GLSRC)gstrans.h $(gstparam_h)
+gstrans_h=$(GLSRC)gstrans.h $(gstparam_h) $(gxcomp_h)
 gsipar3x_h=$(GLSRC)gsipar3x.h $(gsiparam_h) $(gsiparm3_h)
 gximag3x_h=$(GLSRC)gximag3x.h $(gsipar3x_h) $(gxiparam_h)
 gxblend_h=$(GLSRC)gxblend.h
 gdevp14_h=$(GLSRC)gdevp14.h
 
 $(GLOBJ)gstrans.$(OBJ) : $(GLSRC)gstrans.c $(GXERR)\
+ $(math__h) $(memory__h) $(gdevp14_h)\
  $(gstrans_h) $(gsutil_h) $(gxdevcli_h) $(gzstate_h)
 	$(GLCC) $(GLO_)gstrans.$(OBJ) $(C_) $(GLSRC)gstrans.c
 
@@ -2472,7 +2474,7 @@
  $(gscdefs_h) $(gsdevice_h) $(gsdfilt_h) $(gsimage_h)\
  $(gsstruct_h) $(gstparam_h)\
  $(gxblend_h) $(gxdcolor_h) $(gxdevice_h) $(gxiparam_h) $(gxistate_h)\
- $(gxtext_h)\
+ $(gxtext_h) $(gsrect_h) $(gstrans_h) $(gsutil_h) $(gxcldev_h)\
  $(gzstate_h) $(gdevp14_h) $(gsovrc_h) $(gxcmap_h) $(gscolor1_h)
 	$(GLCC) $(GLO_)gdevp14.$(OBJ) $(C_) $(GLSRC)gdevp14.c
 

Index: zdpnext.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/zdpnext.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- zdpnext.c	22 Aug 2002 07:12:29 -0000	1.7
+++ zdpnext.c	14 Mar 2005 18:08:37 -0000	1.8
@@ -370,8 +370,7 @@
 	return code;
     pcp->orig_dev = pcp->cdev = dev;	/* for end_composite */
     code = (*dev_proc(dev, create_compositor))
-	(dev, &pcp->cdev, pcp->pcte, (const gs_imager_state *)igs,
-	 imemory);
+	(dev, &pcp->cdev, pcp->pcte, (gs_imager_state *)igs, imemory);
     if (code < 0) {
 	end_composite(i_ctx_p, pcp);
 	return code;

Index: ztrans.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/ztrans.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- ztrans.c	4 Aug 2004 19:36:13 -0000	1.22
+++ ztrans.c	14 Mar 2005 18:08:37 -0000	1.23
@@ -288,6 +288,7 @@
     pop(5);
     return code;
 }
+
 /* Implement the TransferFunction using a Function. */
 private int
 tf_using_function(floatp in_val, float *out, void *proc_data)
@@ -414,22 +415,25 @@
 private int
 zpushpdf14devicefilter(i_ctx_t *i_ctx_p)
 {
-    gs_device_filter_t *df;
     int code;
-    gs_memory_t *mem = gs_memory_stable(imemory);
     os_ptr op = osp;
 
     check_type(*op, t_integer);
-    code = gs_pdf14_device_filter(&df, op->value.intval, mem);
-    if (code < 0)
-        return code;
-    code = gs_push_device_filter(mem, igs, df); 
+    code = gs_push_pdf14trans_device(igs); 
     if (code < 0)
         return code;
     pop(1);
     return 0;
 }
 
+/* this is a filter operator, but we include it here to maintain
+   modularity of the pdf14 transparency support */
+private int
+zpoppdf14devicefilter(i_ctx_t *i_ctx_p)
+{
+    return gs_pop_pdf14trans_device(igs); 
+}
+
 /* ------ Initialization procedure ------ */
 
 /* We need to split the table because of the 16-element limit. */
@@ -454,5 +458,6 @@
     {"1.inittransparencymask", zinittransparencymask},
     {"1.image3x", zimage3x},
     {"1.pushpdf14devicefilter", zpushpdf14devicefilter},
+    {"0.poppdf14devicefilter", zpoppdf14devicefilter},
     op_def_end(0)
 };



More information about the gs-cvs mailing list