summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2011-07-07 10:41:27 +0100
committerChris Liddell <chris.liddell@artifex.com>2011-07-07 11:34:54 +0100
commit70a824e77c39eed68d7bc7a44351f3beec26fb93 (patch)
tree33de3404a0a1050d354d6f4da48650e706ccc7da
parent11fa4e84f504bdbd9e78495cf5214e49554383b0 (diff)
downloadghostpdl-70a824e77c39eed68d7bc7a44351f3beec26fb93.tar.gz
Bug 688528: set ICC profiles for interal uses of bbox device.
If we create a bbox device internally (i.e. not as an output device) we must still ensure that the device has ICC profiles set in it. In this case, it simply inherits the profile array from the parent device. This also meant moving the ICC manager initialization to before the device "open" call in gs_setdevice_no_erase() because the device set can also open another device (in this case, pswrite's "open" has the effect, via the vector device, of setting a bbox device instance, so there must be an array of ICC profiles at that stage for bbox to inherit. No cluster differences expected.
-rw-r--r--gs/base/gdevvec.c13
-rw-r--r--gs/base/gsdevice.c69
-rw-r--r--gs/base/gslib.c4
-rw-r--r--gs/base/gximag3x.c7
4 files changed, 69 insertions, 24 deletions
diff --git a/gs/base/gdevvec.c b/gs/base/gdevvec.c
index 49c30fbb8..624d7910a 100644
--- a/gs/base/gdevvec.c
+++ b/gs/base/gdevvec.c
@@ -316,6 +316,10 @@ gdev_vector_open_file_options(gx_device_vector * vdev, uint strmbuf_size,
if (vdev->bbox_device) {
gx_device_bbox_init(vdev->bbox_device, NULL, vdev->v_memory);
rc_increment(vdev->bbox_device);
+
+ code = dev_proc(vdev, get_profile)((gx_device *)vdev, &vdev->bbox_device->icc_array);
+ rc_increment(vdev->bbox_device->icc_array);
+
gx_device_set_resolution((gx_device *) vdev->bbox_device,
vdev->HWResolution[0],
vdev->HWResolution[1]);
@@ -802,9 +806,14 @@ gdev_vector_close_file(gx_device_vector * vdev)
FILE *f = vdev->file;
int err;
- gs_free_object(vdev->v_memory, vdev->bbox_device,
+ if (vdev->bbox_device) {
+ rc_decrement(vdev->bbox_device->icc_array, "vector_close(bbox_device->icc_array");
+ vdev->bbox_device->icc_array = NULL;
+ gs_free_object(vdev->v_memory, vdev->bbox_device,
"vector_close(bbox_device)");
- vdev->bbox_device = 0;
+ vdev->bbox_device = 0;
+ }
+
if (vdev->strm) {
sclose(vdev->strm);
gs_free_object(vdev->v_memory, vdev->strm, "vector_close(strm)");
diff --git a/gs/base/gsdevice.c b/gs/base/gsdevice.c
index b4d722c6b..59e8880ba 100644
--- a/gs/base/gsdevice.c
+++ b/gs/base/gsdevice.c
@@ -421,27 +421,6 @@ gs_setdevice_no_erase(gs_state * pgs, gx_device * dev)
int open_code = 0, code;
gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(pgs->memory);
- /* Initialize the device */
- if (!dev->is_open) {
- gx_device_fill_in_procs(dev);
- if (gs_device_is_memory(dev)) {
- /* Set the target to the current device. */
- gx_device *odev = gs_currentdevice_inline(pgs);
-
- while (odev != 0 && gs_device_is_memory(odev))
- odev = ((gx_device_memory *)odev)->target;
- gx_device_set_target(((gx_device_forward *)dev), odev);
- }
- code = open_code = gs_opendevice(dev);
- if (code < 0)
- return code;
- }
- gs_setdevice_no_init(pgs, dev);
- pgs->ctm_default_set = false;
- if ((code = gs_initmatrix(pgs)) < 0 ||
- (code = gs_initclip(pgs)) < 0
- )
- return code;
/* If the ICC manager is not yet initialized, set it up now. But only
if we have file io capability now */
if (libctx->io_device_table != NULL) {
@@ -452,7 +431,7 @@ gs_setdevice_no_erase(gs_state * pgs, gx_device * dev)
gsicc_init_iccmanager(pgs);
}
/* Also, if the device profile is not yet set then take care of that
- before we start filling pages */
+ before we start filling pages, if we can */
if (dev->procs.get_profile != NULL) {
code = dev_proc(dev, get_profile)(dev, &dev_profile);
if (dev_profile == NULL ||
@@ -467,6 +446,52 @@ gs_setdevice_no_erase(gs_state * pgs, gx_device * dev)
}
}
}
+
+ /* Initialize the device */
+ if (!dev->is_open) {
+ gx_device_fill_in_procs(dev);
+
+ /* If we have not yet done so, and if we can, set the device profile
+ * Doing so *before* the device is opened means that a device which
+ * opens other devices can pass a profile on - for example, pswrite
+ * also opens a bbox device
+ */
+ if (libctx->io_device_table != NULL) {
+ cmm_dev_profile_t *dev_profile;
+ const gs_imager_state *pis = (const gs_imager_state* ) pgs;
+ if (dev->procs.get_profile != NULL) {
+ code = dev_proc(dev, get_profile)(dev, &dev_profile);
+ if (dev_profile == NULL ||
+ dev_profile->device_profile[gsDEFAULTPROFILE] == NULL) {
+ /* Go ahead and set the directory in the device params. */
+ gsicc_set_device_icc_dir(pis, pis->icc_manager->profiledir);
+ code = gsicc_init_device_profile_struct(dev, NULL,
+ gsDEFAULTPROFILE);
+ /* set the intent too */
+ code = gsicc_set_device_profile_intent(dev, gsPERCEPTUAL,
+ gsDEFAULTPROFILE);
+ }
+ }
+ }
+
+ if (gs_device_is_memory(dev)) {
+ /* Set the target to the current device. */
+ gx_device *odev = gs_currentdevice_inline(pgs);
+
+ while (odev != 0 && gs_device_is_memory(odev))
+ odev = ((gx_device_memory *)odev)->target;
+ gx_device_set_target(((gx_device_forward *)dev), odev);
+ }
+ code = open_code = gs_opendevice(dev);
+ if (code < 0)
+ return code;
+ }
+ gs_setdevice_no_init(pgs, dev);
+ pgs->ctm_default_set = false;
+ if ((code = gs_initmatrix(pgs)) < 0 ||
+ (code = gs_initclip(pgs)) < 0
+ )
+ return code;
/* If we were in a charpath or a setcachedevice, */
/* we aren't any longer. */
pgs->in_cachedevice = 0;
diff --git a/gs/base/gslib.c b/gs/base/gslib.c
index 2f578a6f4..04d25576f 100644
--- a/gs/base/gslib.c
+++ b/gs/base/gslib.c
@@ -120,6 +120,10 @@ main(int argc, const char *argv[])
gs_alloc_struct_immovable(mem, gx_device_bbox, &st_device_bbox,
"bbox");
gx_device_bbox_init(bbdev, dev, mem);
+
+ code = dev_proc(dev, get_profile)(dev, &bbdev->icc_array);
+ rc_increment(bbdev->icc_array);
+
/* Print out the device name just to test the gsparam.c API. */
{
gs_c_param_list list;
diff --git a/gs/base/gximag3x.c b/gs/base/gximag3x.c
index fa2fd1762..4033caf79 100644
--- a/gs/base/gximag3x.c
+++ b/gs/base/gximag3x.c
@@ -549,6 +549,10 @@ make_mcdex_default(gx_device *dev, const gs_imager_state *pis,
if (bbdev == 0)
return_error(gs_error_VMerror);
gx_device_bbox_init(bbdev, dev, mem);
+
+ code = dev_proc(dev, get_profile)(dev, &bbdev->icc_array);
+ rc_increment(bbdev->icc_array);
+
gx_device_bbox_fwd_open_close(bbdev, false);
code = dev_proc(bbdev, begin_typed_image)
((gx_device *)bbdev, pis, pmat, pic, prect, pdcolor, pcpath, mem,
@@ -858,6 +862,9 @@ gx_image3x_end_image(gx_image_enum_common_t * info, bool draw_last)
gx_device *pcdev = penum->pcdev;
int pcode = gx_image_end(penum->pixel.info, draw_last);
+ rc_decrement(pcdev->icc_array, "gx_image3x_end_image(pcdev->icc_array)");
+ pcdev->icc_array = NULL;
+
gs_closedevice(pcdev);
if (mdev0)
gs_closedevice(mdev0);