summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2011-03-23 21:34:20 +0000
committerMichael Vrhel <michael.vrhel@artifex.com>2011-03-23 21:34:20 +0000
commit95566e8fbb62fdfdf1f04e6600a8b7ba436c43b1 (patch)
tree52da850ab1f7fb712690ccc6330d5d4683f26ad3
parent38679c9d99e40435c854408a80154bf24b139adf (diff)
This commit fixes several issues.
Memory leaks in the PDF14 device as well as the separation devices. Fixes in PDF14 device so the the color encoder and decoder are properly updated if soft masks occur with spot colors. Proper copying of the devicen parameters to the clist devices in the MT rendering. This was the source of a problem when doing multi-threaded rendering to separation devices. This fixes bug 692087 git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@12306 a1074d23-0009-0410-80fe-cf8c14f379e6
-rw-r--r--gs/base/gdevdevn.c150
-rw-r--r--gs/base/gdevdevn.h22
-rw-r--r--gs/base/gdevp14.c114
-rw-r--r--gs/base/gdevp14.h13
-rw-r--r--gs/base/gdevpsd.c3
-rw-r--r--gs/base/gdevtsep.c3
-rw-r--r--gs/base/gsicc_cache.c6
-rw-r--r--gs/base/gxblend.c2
-rw-r--r--gs/base/gxclthrd.c13
-rw-r--r--gs/base/gxclutil.c3
-rw-r--r--gs/base/lib.mak3
11 files changed, 291 insertions, 41 deletions
diff --git a/gs/base/gdevdevn.c b/gs/base/gdevdevn.c
index 78530eaf4..c3491fd50 100644
--- a/gs/base/gdevdevn.c
+++ b/gs/base/gdevdevn.c
@@ -526,6 +526,144 @@ devn_put_params(gx_device * pdev, gs_param_list * plist,
return code;
}
+/* A self referencing function to copy the color list */
+static int
+copy_color_list(compressed_color_list_t *src_color_list,
+ compressed_color_list_t *des_color_list, gs_memory_t *memory)
+{
+ int k;
+ int num_sub_levels = src_color_list->num_sub_level_ptrs;
+
+ if (num_sub_levels > 0) {
+ for (k = 0; k < num_sub_levels; k++) {
+ des_color_list->u.sub_level_ptrs[k] =
+ alloc_compressed_color_list_elem(memory,
+ des_color_list->level_num_comp - 1);
+ if (des_color_list->u.sub_level_ptrs[k] == NULL) {
+ return gs_rethrow(-1, "copy_color_list allocation error");
+ }
+ des_color_list->u.sub_level_ptrs[k]->first_bit_map =
+ src_color_list->u.sub_level_ptrs[k]->first_bit_map;
+ des_color_list->u.sub_level_ptrs[k]->num_sub_level_ptrs =
+ src_color_list->u.sub_level_ptrs[k]->num_sub_level_ptrs;
+ copy_color_list(src_color_list->u.sub_level_ptrs[k],
+ des_color_list->u.sub_level_ptrs[k], memory);
+ }
+ } else {
+ /* Allocate and copy the data */
+ memcpy(&(des_color_list->u.comp_data[0]),
+ &(src_color_list->u.comp_data[0]),
+ size_of(comp_bit_map_list_t)*NUM_ENCODE_LIST_ITEMS);
+ }
+ return 0;
+}
+
+/* Free the copied deviceN parameters */
+void
+devn_free_params(gx_device *thread_cdev)
+{
+ gs_devn_params *devn_params;
+ int k;
+
+ devn_params = dev_proc(thread_cdev, ret_devn_params)(thread_cdev);
+ if (devn_params == NULL) return;
+
+ for (k = 0; k < devn_params->separations.num_separations; k++) {
+ gs_free_object(thread_cdev->memory,
+ devn_params->separations.names[k].data,
+ "devn_free_params");
+ }
+ free_compressed_color_list(thread_cdev->memory,
+ devn_params->compressed_color_list);
+ for (k = 0; k < devn_params->pdf14_separations.num_separations; k++) {
+ gs_free_object(thread_cdev->memory,
+ devn_params->pdf14_separations.names[k].data,
+ "devn_free_params");
+ }
+ free_compressed_color_list(thread_cdev->memory,
+ devn_params->pdf14_compressed_color_list);
+}
+
+/* This is used to copy the deviceN parameters from the parent clist device to the
+ individual thread clist devices for multi-threaded rendering */
+int
+devn_copy_params(gx_device * psrcdev, gx_device * pdesdev)
+{
+ gs_devn_params *src_devn_params, *des_devn_params;
+ int code = 0;
+ int k;
+ compressed_color_list_t *src_color_list, *des_color_list;
+
+ /* Get pointers to the parameters */
+ src_devn_params = dev_proc(psrcdev, ret_devn_params)(psrcdev);
+ des_devn_params = dev_proc(pdesdev, ret_devn_params)(pdesdev);
+ /* First the easy items */
+ des_devn_params->bitspercomponent = src_devn_params->bitspercomponent;
+ des_devn_params->max_separations = src_devn_params->max_separations;
+ des_devn_params->num_separation_order_names =
+ src_devn_params->num_separation_order_names;
+ des_devn_params->num_std_colorant_names =
+ src_devn_params->num_std_colorant_names;
+ des_devn_params->page_spot_colors = src_devn_params->page_spot_colors;
+ des_devn_params->std_colorant_names = src_devn_params->std_colorant_names;
+ des_devn_params->separations.num_separations
+ = src_devn_params->separations.num_separations;
+ /* Now the more complex structures */
+ /* Spot color names */
+ for (k = 0; k < des_devn_params->separations.num_separations; k++) {
+ byte * sep_name;
+ int name_size = src_devn_params->separations.names[k].size;
+ sep_name = (byte *)gs_alloc_bytes(pdesdev->memory->stable_memory,
+ name_size, "devn_copy_params");
+ memcpy(sep_name, src_devn_params->separations.names[k].data, name_size);
+ des_devn_params->separations.names[k].size = name_size;
+ des_devn_params->separations.names[k].data = sep_name;
+ }
+ /* Order map */
+ memcpy(des_devn_params->separation_order_map,
+ src_devn_params->separation_order_map, sizeof(gs_separation_map));
+ /* Compressed color list. A messy structure that has a union that
+ includes a linked list item */
+ src_color_list = src_devn_params->compressed_color_list;
+ if (src_color_list != NULL) {
+ /* Take care of the initial one. Others are done recursively */
+ des_color_list = alloc_compressed_color_list_elem(pdesdev->memory,
+ TOP_ENCODED_LEVEL);
+ des_color_list->first_bit_map = src_color_list->first_bit_map;
+ des_color_list->num_sub_level_ptrs = src_color_list->num_sub_level_ptrs;
+ code = copy_color_list(src_color_list, des_color_list, pdesdev->memory);
+ des_devn_params->compressed_color_list = des_color_list;
+ } else {
+ des_devn_params->compressed_color_list = NULL;
+ }
+ /* Handle the PDF14 items if they are there */
+ des_devn_params->pdf14_separations.num_separations
+ = src_devn_params->pdf14_separations.num_separations;
+ for (k = 0; k < des_devn_params->pdf14_separations.num_separations; k++) {
+ byte * sep_name;
+ int name_size = src_devn_params->pdf14_separations.names[k].size;
+ sep_name = (byte *)gs_alloc_bytes(pdesdev->memory->stable_memory,
+ name_size, "devn_copy_params");
+ memcpy(sep_name, src_devn_params->pdf14_separations.names[k].data,
+ name_size);
+ des_devn_params->pdf14_separations.names[k].size = name_size;
+ des_devn_params->pdf14_separations.names[k].data = sep_name;
+ }
+ src_color_list = src_devn_params->pdf14_compressed_color_list;
+ if (src_color_list != NULL) {
+ /* Take care of the initial one. Others are done recursively */
+ des_color_list = alloc_compressed_color_list_elem(pdesdev->memory,
+ TOP_ENCODED_LEVEL);
+ des_color_list->first_bit_map = src_color_list->first_bit_map;
+ des_color_list->num_sub_level_ptrs = src_color_list->num_sub_level_ptrs;
+ code = copy_color_list(src_color_list, des_color_list, pdesdev->memory);
+ des_devn_params->pdf14_compressed_color_list = des_color_list;
+ } else {
+ des_devn_params->pdf14_compressed_color_list = NULL;
+ }
+ return code;
+}
+
/*
* Utility routine for handling DeviceN related parameters in a
* standard raster printer type device.
@@ -675,8 +813,8 @@ compressed_color_list_t *
alloc_compressed_color_list_elem(gs_memory_t * mem, int num_comps)
{
compressed_color_list_t * plist =
- gs_alloc_struct(mem, compressed_color_list_t, &st_compressed_color_list,
- "alloc_compressed_color_list");
+ gs_alloc_struct(mem->stable_memory, compressed_color_list_t,
+ &st_compressed_color_list, "alloc_compressed_color_list");
if (plist != NULL) {
/* Initialize the data in the element. */
memset(plist, 0, size_of(*plist));
@@ -699,10 +837,12 @@ free_compressed_color_list(gs_memory_t * mem,
return;
/* Discard the sub levels. */
+ /* Allocation for this object is done in stable memory. Make sure
+ that is done here too */
for (i = 0; i < pcomp_list->num_sub_level_ptrs; i++)
- free_compressed_color_list(mem, pcomp_list->u.sub_level_ptrs[i]);
-
- gs_free_object(mem, pcomp_list, "free_compressed_color_list");
+ free_compressed_color_list(mem->stable_memory,
+ pcomp_list->u.sub_level_ptrs[i]);
+ gs_free_object(mem->stable_memory, pcomp_list, "free_compressed_color_list");
return;
}
diff --git a/gs/base/gdevdevn.h b/gs/base/gdevdevn.h
index 7af781801..77fdd630d 100644
--- a/gs/base/gdevdevn.h
+++ b/gs/base/gdevdevn.h
@@ -257,6 +257,28 @@ int check_pcm_and_separation_names(const gx_device * dev,
const gs_devn_params * pparams, const char * pname,
int name_size, int component_type);
+/*
+ * This routine copies over the gs_devn_params from one device to another.
+ This is needed when we launch multi-threaded rendering for separation
+ devices
+ *
+ * Parameters :
+ * psrcdev - pointer to source device.
+ * pdesdev - pointer to destination device.
+ *
+ * Returns 0 if all allocations were fine.
+ */
+int devn_copy_params(gx_device * psrcdev, gx_device * pdesdev);
+
+/*
+ * This routine frees the gs_devn_params objects
+ *
+ * Parameters :
+ * dev - pointer to device.
+ *
+ */
+void devn_free_params(gx_device *dev);
+
/*
* This routine will extract a specified set of bits from a buffer and pack
* them into a given buffer.
diff --git a/gs/base/gdevp14.c b/gs/base/gdevp14.c
index 925cecb66..7b2d857cf 100644
--- a/gs/base/gdevp14.c
+++ b/gs/base/gdevp14.c
@@ -168,6 +168,7 @@ static dev_proc_pattern_manage(pdf14_pattern_manage);
static int pdf14_clist_get_param_compressed_color_list(pdf14_device * p14dev);
static dev_proc_push_transparency_state(pdf14_push_transparency_state);
static dev_proc_pop_transparency_state(pdf14_pop_transparency_state);
+static dev_proc_ret_devn_params(pdf14_ret_devn_params);
static const gx_color_map_procs *
pdf14_get_cmap_procs(const gs_imager_state *, const gx_device *);
@@ -241,7 +242,7 @@ static const gx_color_map_procs *
NULL, /* fill_linear_color_trapezoid */\
NULL, /* fill_linear_color_triangle */\
gx_forward_update_spot_equivalent_colors, /* update spot */\
- NULL, /* DevN params */\
+ pdf14_ret_devn_params, /* DevN params */\
NULL, /* fill page */\
pdf14_push_transparency_state,\
pdf14_pop_transparency_state\
@@ -540,6 +541,8 @@ pdf14_buf_new(gs_int_rect *rect, bool has_tags, bool has_alpha_g,
result->parent_color_info_procs->parent_color_comp_index = NULL;
result->parent_color_info_procs->icc_profile = NULL;
result->parent_color_info_procs->previous = NULL;
+ result->parent_color_info_procs->encode = NULL;
+ result->parent_color_info_procs->decode = NULL;
if (height <= 0) {
/* Empty clipping - will skip all drawings. */
result->planestride = 0;
@@ -1309,6 +1312,7 @@ pdf14_open(gx_device *dev)
pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, dev->memory);
if (pdev->ctx == NULL)
return_error(gs_error_VMerror);
+ pdev->free_devicen = true;
return 0;
}
@@ -2648,6 +2652,13 @@ gx_update_pdf14_compositor(gx_device * pdev, gs_imager_state * pis,
new_is.log_op = rop3_default;
p14dev->pdf14_procs->put_image(pdev, &new_is, p14dev->target);
}
+ /* Before we disable the device release any deviceN structures.
+ free_devicen is set if the pdf14 device had inherited its
+ deviceN parameters from the target clist device. In this
+ case they should not be freed */
+ if (p14dev->free_devicen) {
+ devn_free_params(pdev);
+ }
pdf14_disable_device(pdev);
pdf14_close(pdev);
break;
@@ -3049,6 +3060,9 @@ pdf14_end_transparency_group(gx_device *dev,
parent_color->parent_color_comp_index = NULL;
parent_color->parent_color_mapping_procs = NULL;
if (parent_color->icc_profile != NULL) {
+ /* make sure to decrement the device profile. If it was allocated
+ with the push then it will be freed. */
+ rc_decrement(dev->device_icc_profile,"pdf14_end_transparency_group");
dev->device_icc_profile = parent_color->icc_profile;
rc_decrement(parent_color->icc_profile,"pdf14_end_transparency_group");
parent_color->icc_profile = NULL;
@@ -3153,8 +3167,13 @@ pdf14_update_device_color_procs(gx_device *dev,
if (iccprofile == NULL)
return gs_rethrow(-1,"ICC data not found in clist");
/* Keep a pointer to the clist device */
- iccprofile->dev = (gx_device *) pcrdev;
- }
+ iccprofile->dev = (gx_device *) pcrdev;
+ } else {
+ /* Go ahead and rc increment right now. This way when
+ we pop, we will make sure to decrement and avoid a
+ leak for the above profile that we just created */
+ rc_increment(iccprofile);
+ }
new_num_comps = iccprofile->num_comps;
new_depth = new_num_comps * 8;
if (new_num_comps == 4) {
@@ -3214,14 +3233,25 @@ pdf14_update_device_color_procs(gx_device *dev,
GX_DEVICE_COLOR_MAX_COMPONENTS);
parent_color_info->max_color = pdev->color_info.max_color;
parent_color_info->max_gray = pdev->color_info.max_gray;
-
+ parent_color_info->encode = pdev->procs.encode_color;
+ parent_color_info->decode = pdev->procs.decode_color;
/* Don't increment the space since we are going to remove it from the
ICC manager anyway. */
if (group_color == ICC && iccprofile != NULL) {
parent_color_info->icc_profile = dev->device_icc_profile;
}
-
/* Set new information */
+ /* If we are in a soft mask and we are using compressed color
+ encoding, then go ahead and update the encoder and decoder. */
+ if (pdev->procs.encode_color == pdf14_compressed_encode_color &&
+ new_num_comps == 1) {
+ pdev->procs.decode_color = pdevproto->static_procs->decode_color;
+ if (has_tags) {
+ pdev->procs.encode_color = pdf14_encode_color_tag;
+ } else {
+ pdev->procs.encode_color = pdevproto->static_procs->encode_color;
+ }
+ }
pis->get_cmap_procs = pdf14_get_cmap_procs_group;
gx_set_cmap_procs(pis, dev);
pdev->procs.get_color_mapping_procs =
@@ -3247,6 +3277,9 @@ pdf14_update_device_color_procs(gx_device *dev,
in the ICC manager, since that is the profile that is used for the
PDF14 device */
if (group_color == ICC && iccprofile != NULL) {
+ /* iccprofile was incremented above if we had not just created
+ it. when we do the pop we will decrement and if we just
+ created it, it will be destroyed */
dev->device_icc_profile = iccprofile;
rc_increment(parent_color_info->icc_profile);
}
@@ -3411,6 +3444,24 @@ pdf14_update_device_color_procs_push_c(gx_device *dev,
memset(&(pdev->color_info.comp_shift),0,GX_DEVICE_COLOR_MAX_COMPONENTS);
memcpy(&(pdev->color_info.comp_bits),comp_bits,4);
memcpy(&(pdev->color_info.comp_shift),comp_shift,4);
+ /* If we have a compressed color codec, and we are doing a soft mask
+ push operation then go ahead and update the color encode and
+ decode for the pdf14 device to not used compressed color
+ encoding while in the soft mask. We will just check for gray
+ and compressed. Note that we probably don't have_tags if we
+ are dealing with compressed color. But is is possible so
+ we add it in to catch for future use. */
+ if (pdev->procs.encode_color == pdf14_compressed_encode_color &&
+ new_num_comps == 1) {
+ pdev->procs.decode_color =
+ pdevproto->static_procs->decode_color;
+ if (has_tags) {
+ pdev->procs.encode_color = pdf14_encode_color_tag;
+ } else {
+ pdev->procs.encode_color =
+ pdevproto->static_procs->encode_color;
+ }
+ }
cldev->clist_color_info.depth = pdev->color_info.depth;
cldev->clist_color_info.polarity = pdev->color_info.polarity;
cldev->clist_color_info.num_components = pdev->color_info.num_components;
@@ -3456,6 +3507,8 @@ pdf14_update_device_color_procs_pop_c(gx_device *dev,gs_imager_state *pis)
pdev->pdf14_procs = parent_color->unpack_procs;
pdev->color_info.max_color = parent_color->max_color;
pdev->color_info.max_gray = parent_color->max_gray;
+ pdev->procs.encode_color = parent_color->encode;
+ pdev->procs.decode_color = parent_color->decode;
memcpy(&(pdev->color_info.comp_bits),&(parent_color->comp_bits),
GX_DEVICE_COLOR_MAX_COMPONENTS);
memcpy(&(pdev->color_info.comp_shift),&(parent_color->comp_shift),
@@ -3520,6 +3573,8 @@ pdf14_push_parent_color(gx_device *dev, const gs_imager_state *pis)
new_parent_color->depth = pdev->color_info.depth;
new_parent_color->max_color = pdev->color_info.max_color;
new_parent_color->max_gray = pdev->color_info.max_gray;
+ new_parent_color->decode = pdev->procs.decode_color;
+ new_parent_color->encode = pdev->procs.encode_color;
memcpy(&(new_parent_color->comp_bits),&(pdev->color_info.comp_bits),
GX_DEVICE_COLOR_MAX_COMPONENTS);
memcpy(&(new_parent_color->comp_shift),&(pdev->color_info.comp_shift),
@@ -3643,26 +3698,29 @@ pdf14_end_transparency_mask(gx_device *dev, gs_imager_state *pis,
if (!(parent_color->parent_color_mapping_procs == NULL &&
parent_color->parent_color_comp_index == NULL)) {
pis->get_cmap_procs = parent_color->get_cmap_procs;
- gx_set_cmap_procs(pis, dev);
- pdev->procs.get_color_mapping_procs = parent_color->parent_color_mapping_procs;
- pdev->procs.get_color_comp_index = parent_color->parent_color_comp_index;
- pdev->color_info.polarity = parent_color->polarity;
- pdev->color_info.num_components = parent_color->num_components;
- pdev->color_info.depth = parent_color->depth;
- pdev->blend_procs = parent_color->parent_blending_procs;
- pdev->ctx->additive = parent_color->isadditive;
- pdev->pdf14_procs = parent_color->unpack_procs;
+ gx_set_cmap_procs(pis, dev);
+ pdev->procs.get_color_mapping_procs = parent_color->parent_color_mapping_procs;
+ pdev->procs.get_color_comp_index = parent_color->parent_color_comp_index;
+ pdev->color_info.polarity = parent_color->polarity;
+ pdev->color_info.num_components = parent_color->num_components;
+ pdev->color_info.depth = parent_color->depth;
+ pdev->blend_procs = parent_color->parent_blending_procs;
+ pdev->ctx->additive = parent_color->isadditive;
+ pdev->pdf14_procs = parent_color->unpack_procs;
pdev->color_info.max_color = parent_color->max_color;
pdev->color_info.max_gray = parent_color->max_gray;
- parent_color->get_cmap_procs = NULL;
- parent_color->parent_color_comp_index = NULL;
- parent_color->parent_color_mapping_procs = NULL;
+ parent_color->get_cmap_procs = NULL;
+ parent_color->parent_color_comp_index = NULL;
+ parent_color->parent_color_mapping_procs = NULL;
+ pdev->procs.encode_color = parent_color->encode;
+ pdev->procs.decode_color = parent_color->decode;
memcpy(&(pdev->color_info.comp_bits),&(parent_color->comp_bits),
GX_DEVICE_COLOR_MAX_COMPONENTS);
memcpy(&(pdev->color_info.comp_shift),&(parent_color->comp_shift),
GX_DEVICE_COLOR_MAX_COMPONENTS);
/* Take care of the ICC profile */
if (parent_color->icc_profile != NULL) {
+ rc_decrement(dev->device_icc_profile,"pdf14_end_transparency_mask");
dev->device_icc_profile = parent_color->icc_profile;
rc_decrement(parent_color->icc_profile,"pdf14_end_transparency_mask");
parent_color->icc_profile = NULL;
@@ -5650,7 +5708,7 @@ get_param_compressed_color_list_elem(pdf14_clist_device * pdev,
pkeyname_list);
}
- return 0;;
+ return 0;
}
#undef put_data
@@ -5727,6 +5785,17 @@ put_param_compressed_color_list_elem(gx_device * pdev,
#undef get_data
/*
+ * devicen params
+ */
+gs_devn_params *
+pdf14_ret_devn_params(gx_device *pdev)
+{
+ pdf14_device *p14dev = (pdf14_device *)pdev;
+
+ return(&(p14dev->devn_params));
+}
+
+/*
* Convert a list of spot color names into a set of device parameters.
* This is done to transfer information from the PDf14 clist writer
* compositing device to the PDF14 clist reader compositing device.
@@ -6657,15 +6726,14 @@ c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
p14dev->devn_params.num_std_colorant_names +
p14dev->devn_params.page_spot_colors;
}
- /* Transfer the data for the compressed color encoding. */
- /* free_compressed_color_list(p14dev->memory,
- p14dev->devn_params.compressed_color_list); */
+ /* Transfer the data for the compressed color encoding.
+ But we have to free what may be there before we do this */
+ devn_free_params((gx_device*) p14dev);
p14dev->devn_params.compressed_color_list =
pclist_devn_params->pdf14_compressed_color_list;
- /* free_separation_names(p14dev->memory,
- &p14dev->devn_params.separations); */
p14dev->devn_params.separations =
pclist_devn_params->pdf14_separations;
+ p14dev->free_devicen = false; /* to avoid freeing the clist ones */
if (num_comp != p14dev->color_info.num_components) {
/* When the pdf14 device is opened it creates a context
and some soft mask related objects. The push device
diff --git a/gs/base/gdevp14.h b/gs/base/gdevp14.h
index 0c1ead419..73580f4f1 100644
--- a/gs/base/gdevp14.h
+++ b/gs/base/gdevp14.h
@@ -103,7 +103,6 @@ struct pdf14_mask_s {
typedef struct pdf14_parent_color_s pdf14_parent_color_t;
struct pdf14_parent_color_s {
-
int num_components;
bool isadditive;
gx_color_polarity_t polarity;
@@ -114,13 +113,14 @@ struct pdf14_parent_color_s {
uint max_color; /* Causes issues if these are not maintained */
const gx_color_map_procs *(*get_cmap_procs)(const gs_imager_state *,
const gx_device *);
- const gx_cm_color_map_procs *(*parent_color_mapping_procs)(const gx_device *);
+ gx_cm_color_map_procs *(*parent_color_mapping_procs)(const gx_device *);
+ gx_color_index (*encode)(gx_device *, const gx_color_value value[]);
+ int (*decode)(gx_device *, gx_color_index, gx_color_value *);
int (*parent_color_comp_index)(gx_device *, const char *, int, int);
const pdf14_procs_t * unpack_procs;
const pdf14_nonseparable_blending_procs_t * parent_blending_procs;
cmm_profile_t *icc_profile; /* Opaque to GC. Allocated in non-gc memory */
pdf14_parent_color_t *previous;
-
};
typedef struct pdf14_ctx_s pdf14_ctx;
@@ -224,10 +224,11 @@ typedef struct pdf14_device_s {
float alpha; /* alpha = opacity * shape */
gs_blend_mode_t blend_mode;
bool text_knockout;
- bool overprint;
- bool overprint_mode;
- gx_color_index drawn_comps; /* Used for overprinting. Passed from overprint compositor */
+ bool overprint;
+ bool overprint_mode;
+ gx_color_index drawn_comps; /* Used for overprinting. Passed from overprint compositor */
gx_device * pclist_device;
+ bool free_devicen; /* Used to avoid freeing a deviceN parameter from target clist device */
const gx_color_map_procs *(*save_get_cmap_procs)(const gs_imager_state *,
const gx_device *);
gx_device_color_info saved_target_color_info;
diff --git a/gs/base/gdevpsd.c b/gs/base/gdevpsd.c
index 03eaa17c7..8f7ce940a 100644
--- a/gs/base/gdevpsd.c
+++ b/gs/base/gdevpsd.c
@@ -152,6 +152,9 @@ RELOC_PTRS_END
static void
psd_device_finalize(void *vpdev)
{
+ /* We need to deallocate the compressed_color_list.
+ and the names. */
+ devn_free_params((gx_device*) vpdev);
gx_device_finalize(vpdev);
}
diff --git a/gs/base/gdevtsep.c b/gs/base/gdevtsep.c
index 50235ca83..8911ffac9 100644
--- a/gs/base/gdevtsep.c
+++ b/gs/base/gdevtsep.c
@@ -334,6 +334,9 @@ RELOC_PTRS_END
static void
tiffsep_device_finalize(void *vpdev)
{
+ /* We need to deallocate the compressed_color_list.
+ and the names. */
+ devn_free_params((gx_device*) vpdev);
gx_device_finalize(vpdev);
}
diff --git a/gs/base/gsicc_cache.c b/gs/base/gsicc_cache.c
index 224c23b3b..53f499040 100644
--- a/gs/base/gsicc_cache.c
+++ b/gs/base/gsicc_cache.c
@@ -551,7 +551,8 @@ gsicc_get_link_profile(gs_imager_state *pis, gx_device *dev,
really shared amongst threads like the links are. Hence
the memory is for the local thread's chunk */
cms_input_profile =
- gsicc_get_profile_handle_clist(gs_input_profile, memory);
+ gsicc_get_profile_handle_clist(gs_input_profile,
+ gs_input_profile->memory);
gs_input_profile->profile_handle = cms_input_profile;
} else {
/* Cant create the link. No profile present,
@@ -577,7 +578,8 @@ gsicc_get_link_profile(gs_imager_state *pis, gx_device *dev,
/* ICC profile should be in clist. This is
the first call to it. */
cms_output_profile =
- gsicc_get_profile_handle_clist(gs_output_profile, cache_mem);
+ gsicc_get_profile_handle_clist(gs_output_profile,
+ gs_output_profile->memory);
gs_output_profile->profile_handle = cms_output_profile;
} else {
/* Cant create the link. No profile present,
diff --git a/gs/base/gxblend.c b/gs/base/gxblend.c
index e6228b565..c09ccac7a 100644
--- a/gs/base/gxblend.c
+++ b/gs/base/gxblend.c
@@ -1463,7 +1463,7 @@ dump_raw_buffer(int num_rows, int width, int n_chan,
/* clist_band_count is incremented at every pdf14putimage */
/* Useful for catching this thing and only dumping */
/* during a particular band if we have a large file */
- // if (clist_band_count != 1) return;
+ /* if (clist_band_count != 65) return; */
buff_ptr = Buffer;
max_bands = ( n_chan < 57 ? n_chan : 56); /* Photoshop handles at most 56 bands */
sprintf(full_file_name,"%d)%s_%dx%dx%d.raw",global_index,filename,width,num_rows,max_bands);
diff --git a/gs/base/gxclthrd.c b/gs/base/gxclthrd.c
index a5345d09d..54f0fcb4b 100644
--- a/gs/base/gxclthrd.c
+++ b/gs/base/gxclthrd.c
@@ -30,6 +30,7 @@
#include "gsmchunk.h"
#include "gsmemlok.h"
#include "gxclthrd.h"
+#include "gdevdevn.h"
/* Forward reference prototypes */
static int clist_start_render_thread(gx_device *dev, int thread_index, int band);
@@ -51,6 +52,7 @@ clist_setup_render_threads(gx_device *dev, int y)
int i, code, band;
int band_count = cdev->nbands;
char fmode[4];
+ gs_devn_params *pclist_devn_params;
crdev->num_render_threads = pdev->num_render_threads_requested;
@@ -149,6 +151,13 @@ clist_setup_render_threads(gx_device *dev, int y)
ndev->PageCount = dev->PageCount; /* copy to prevent mismatch error */
if ((code = gs_putdeviceparams(ndev, (gs_param_list *)&paramlist)) < 0)
break;
+ /* In the case of a separation device, we need to make sure we get the
+ devn params copied over */
+ pclist_devn_params = dev_proc(dev, ret_devn_params)(dev);
+ if (pclist_devn_params != NULL) {
+ code = devn_copy_params(dev, (gx_device*) ncdev);
+ if (code < 0) return_error(gs_error_VMerror);
+ }
/* A question is, can the clist instances share the device profile.
Only doing reads of this from different threads */
ncdev->device_icc_profile = cdev->device_icc_profile;
@@ -293,7 +302,9 @@ clist_teardown_render_threads(gx_device *dev)
gdev_prn_free_memory((gx_device *)thread_cdev);
/* Decrement the rc count on the icc profile */
rc_decrement(thread_cdev->device_icc_profile,"clist_teardown_render_threads");
- /* Free the device copy this thread used */
+ /* Free the device copy this thread used. Note that the
+ deviceN stuff if was allocated and copied earlier for the device
+ will be freed with this call */
gs_free_object(thread->memory, thread_cdev, "clist_teardown_render_threads");
#ifdef DEBUG
if (gs_debug[':'])
diff --git a/gs/base/gxclutil.c b/gs/base/gxclutil.c
index 89e009387..4bccd873a 100644
--- a/gs/base/gxclutil.c
+++ b/gs/base/gxclutil.c
@@ -577,8 +577,7 @@ cmd_put_color(gx_device_clist_writer * cldev, gx_clist_state * pcls,
}
}
/* Now send one of the two command forms */
- if (use_delta && ((delta_bytes < num_bytes - bytes_dropped))
- || ((num_bytes - bytes_dropped) < 0)) {
+ if (use_delta && delta_bytes < (num_bytes - bytes_dropped)) {
code = set_cmd_put_op(dp, cldev, pcls,
op_delta, delta_bytes + 1);
if (code < 0)
diff --git a/gs/base/lib.mak b/gs/base/lib.mak
index 407b2e807..e46293dbd 100644
--- a/gs/base/lib.mak
+++ b/gs/base/lib.mak
@@ -1827,7 +1827,8 @@ $(GLOBJ)gxclzlib.$(OBJ) : $(GLSRC)gxclzlib.c $(std_h)\
# Support for multi-threaded rendering from the clist. The chunk memory wrapper
# is used to prevent mutex (locking) contention among threads. The underlying
# memory allocator must implement the mutex (non-gc memory is usually gsmalloc)
-$(GLOBJ)gxclthrd.$(OBJ) : $(GLSRC)gxclthrd.c $(gxclist_h) $(gxsync_h) $(gxclthrd_h)
+$(GLOBJ)gxclthrd.$(OBJ) : $(GLSRC)gxclthrd.c $(gxclist_h) $(gxsync_h) $(gxclthrd_h)\
+ $(gdevdevn_h)
$(GLCC) $(GLO_)gxclthrd.$(OBJ) $(C_) $(GLSRC)gxclthrd.c
$(GLOBJ)gsmchunk.$(OBJ) : $(GLSRC)gsmchunk.c $(gx_h) $(gsstype_h) $(gserrors_h)\