c_pdf14trans_clist_read_update(gs_composite_t *	pcte, gx_device	* cdev,
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
{
    pdf14_device * p14dev = (pdf14_device *)tdev;
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
    gs_devn_params * pclist_devn_params;
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
    gsicc_rendering_param_t render_cond;
    cmm_dev_profile_t *dev_profile;

    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
                          &render_cond);
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
                          &render_cond);
    /*
     * 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:
            /* If the CMM is not threadsafe, then the pdf14 device actually
               needs to inherit the ICC profile from the clist thread device
               not the target device.   */
#if !CMM_THREAD_SAFE
            gx_monitor_enter(p14_icc_profile->lock);
            rc_assign(p14dev->icc_struct->device_profile[0], cl_icc_profile,
                      "c_pdf14trans_clist_read_update");
            gx_monitor_leave(p14_icc_profile->lock);
#endif
            /*
             * If we are blending using spot colors (i.e. the output device
             * supports spot colors) then we need to transfer
             * color info from the clist PDF 1.4 compositing reader device
             * to the clist writer PDF 1.4 compositing device.
             * This info was transfered from that device to the output
             * device as a set of device parameters.  However the clist
             * reader PDF 1.4 compositing device did not exist when the
             * device parameters were read from the clist.  So that info
             * was buffered into the output device.
             */
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors != 0) {
                int num_comp = p14dev->color_info.num_components;
                /*
                 * The number of components for the PDF14 device is the sum
                 * of the process components and the number of spot colors
                 * for the page.  If the color capabilities of the parent
                 * device (which coming into this are the same as the p14dev)
                 * are smaller than the number of page spot colors then
                 * use that for the number of components. Otherwise use
                 * the page_spot_colors.
                 */
                p14dev->devn_params.page_spot_colors =
                    pclist_devn_params->page_spot_colors;
                if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
                    p14dev->color_info.num_components = num_comp;
                } else {
                    p14dev->color_info.num_components =
                        p14dev->devn_params.num_std_colorant_names +
                        p14dev->devn_params.page_spot_colors;
                }
                /* Transfer the data for the spot color names
                   But we have to free what may be there before we do this */
                devn_free_params((gx_device*) p14dev);
                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
                       compositor action will have already created these but
                       they are the wrong size.  We must destroy them though
                       before reopening the device */
                    if (p14dev->ctx != NULL) {
                        pdf14_ctx_free(p14dev->ctx);
                    }
                    dev_proc(tdev, open_device) (tdev);
                }
            }
            /* Check if we need to swap out the ICC profile for the pdf14
               device.  This will occur if our source profile for our device
               happens to be something like CIELAB.  Then we will blend in
               RGB (unless a trans group is specified) */
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
                cl_icc_profile =
                    gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
                /* Keep a pointer to the clist device */
                cl_icc_profile->dev = (gx_device *) cdev;
                gx_monitor_enter(p14_icc_profile->lock);
                rc_assign(p14dev->icc_struct->device_profile[0], cl_icc_profile,
                          "c_pdf14trans_clist_read_update");
                /* Initial ref count was ok.  remove increment from assign */
                rc_decrement(p14dev->icc_struct->device_profile[0],
                             "c_pdf14trans_clist_read_update");
                gx_monitor_leave(p14_icc_profile->lock);
            }
            break;

        case PDF14_POP_DEVICE:
#	    if 0 /* Disabled because *p14dev has no forwarding methods during
                    the clist playback. This code is not executed while clist
                    writing. */
            cdev->color_info = p14dev->saved_target_color_info;
#	    endif
            break;

        default:
            break;		/* do nothing for remaining ops */
    }

    return 0;
}
c_pdf14trans_clist_read_update(gs_composite_t *	pcte, gx_device	* cdev,
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
{
    pdf14_device * p14dev = (pdf14_device *)tdev;
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
    gs_devn_params * pclist_devn_params;
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
    gsicc_rendering_param_t render_cond;
    cmm_dev_profile_t *dev_profile;

    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
                          &render_cond);
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
                          &render_cond);
     
    switch (pdf14pct->params.pdf14_op) {
        case PDF14_PUSH_DEVICE:
             
#if !CMM_THREAD_SAFE
            gx_monitor_enter(p14_icc_profile->lock);
            rc_assign(p14dev->icc_struct->device_profile[0], cl_icc_profile,
                      "c_pdf14trans_clist_read_update");
            gx_monitor_leave(p14_icc_profile->lock);
#endif
             
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors != 0) {
                int num_comp = p14dev->color_info.num_components;
                 
                p14dev->devn_params.page_spot_colors =
                    pclist_devn_params->page_spot_colors;
                if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
                    p14dev->color_info.num_components = num_comp;
                } else {
                    p14dev->color_info.num_components =
                        p14dev->devn_params.num_std_colorant_names +
                        p14dev->devn_params.page_spot_colors;
                }
                 
                devn_free_params((gx_device*) p14dev);
                p14dev->devn_params.separations =
                    pclist_devn_params->pdf14_separations;
                p14dev->free_devicen = false;   
                if (num_comp != p14dev->color_info.num_components) {
                     
                    if (p14dev->ctx != NULL) {
                        pdf14_ctx_free(p14dev->ctx);
                    }
                    dev_proc(tdev, open_device) (tdev);
                }
            }
             
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
                cl_icc_profile =
                    gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
                 
                cl_icc_profile->dev = (gx_device *) cdev;
                gx_monitor_enter(p14_icc_profile->lock);
                rc_assign(p14dev->icc_struct->device_profile[0], cl_icc_profile,
                          "c_pdf14trans_clist_read_update");
                 
                rc_decrement(p14dev->icc_struct->device_profile[0],
                             "c_pdf14trans_clist_read_update");
                gx_monitor_leave(p14_icc_profile->lock);
            }
            break;

        case PDF14_POP_DEVICE:
#	    if 0  
            cdev->color_info = p14dev->saved_target_color_info;
#	    endif
            break;

        default:
            break;		 
    }

    return 0;
}