pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
                                 bool *using_blend_cs)
{
    /* If a blend color space was specified, then go ahead and use that to
       define the default color space for the blend modes.  Only Gray, RGB
       or CMYK blend color spaces are allowed.  Note we do not allow this
       setting if we are dealing with a separation device. */
    cmm_dev_profile_t *dev_profile;
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
    bool valid_blend_cs = false;
    *using_blend_cs = false;

    /* Make sure any specified blend color space is valid along with other cond */
    if (code == 0 && dev_profile->blend_profile != NULL && !use_pdf14_accum) {
        if (!dev_profile->blend_profile->isdevlink &&
            !dev_profile->blend_profile->islab &&
            (dev_profile->blend_profile->data_cs == gsGRAY ||
             dev_profile->blend_profile->data_cs == gsRGB ||
             dev_profile->blend_profile->data_cs == gsCMYK)) {
            /* Also, do not allow the use of the blend space when we are pushing
               a pattern pdf14 device.  Those should inherit from the parent */
            if (!(gx_device_is_pattern_clist(pdev) ||
                  gx_device_is_pattern_accum(pdev))) {
                valid_blend_cs = true;
            }
        }
    }

    /* If num components is one, just go ahead and use gray.  This avoids
       issues with additive/subtractive mono color devices  */
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
        pdev->color_info.num_components == 1) {
        /*
        * Note:  We do not allow the SeparationOrder device parameter for
        * additive devices.  Thus we always have 1 colorant for DeviceGray
        * and 3 colorants for DeviceRGB.
        */
        if (valid_blend_cs) {
            *using_blend_cs = true;
            switch (dev_profile->blend_profile->num_comps) {
            case 1:
                return PDF14_DeviceGray;
            case 3:
                return PDF14_DeviceRGB;
            case 4:
                return PDF14_DeviceCMYK;
            }
        }
        if (pdev->color_info.num_components == 1)
            return PDF14_DeviceGray;
        else
            return PDF14_DeviceRGB;
    } else {
        /*
         * Check if the device is CMYK only or CMYK plus spot colors. Note
         * the CMYK plus spot colors will not support the blend color space
         */
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
        return PDF14_DeviceCustom;
#endif
        /*
         * Count the number of CMYK process components supported by the output
         * device.
         */
        for (i = 0; i < 4; i++) {
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];

            output_comp_num = dev_proc(pdev, get_color_comp_index)
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE);
            if (output_comp_num >= 0) {
                num_cmyk++;
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
                    num_cmyk_used++;
            }
        }
        /*
         * Check if the device supports only CMYK.  Otherewise we assume that
         * the output device supports spot colors.  Note:  This algorithm can
         * be fooled if the SeparationOrder device parameter is being used by
         * the output device device to only select CMYK.
         */
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
            && pdev->color_info.max_components == 4) {
            if (valid_blend_cs) {
                *using_blend_cs = true;
                switch (dev_profile->blend_profile->num_comps) {
                case 1:
                    return PDF14_DeviceGray;
                case 3:
                    return PDF14_DeviceRGB;
                case 4:
                    return PDF14_DeviceCMYK;
                }
            }
            return PDF14_DeviceCMYK;
        }
        /*
         * Check if we should use the 'custom' PDF 1.4 compositor device.
         * This device is only needed for those devices which do not support
         * a basic CMYK process color model.
         */
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
        if (num_cmyk != 4)
            return PDF14_DeviceCustom;
#endif
        /*
         * Otherewise we use a CMYK plus spot colors for blending.
         */
        return PDF14_DeviceCMYKspot;
    }
}

pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
                                 bool *using_blend_cs)
{
    /* If a blend color space was specified, then go ahead and use that to
       define the default color space for the blend modes.  Only Gray, RGB
       or CMYK blend color spaces are allowed.  Note we do not allow this
       setting if we are dealing with a separation device. */
    cmm_dev_profile_t *dev_profile;
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
    bool valid_blend_cs = false;
    *using_blend_cs = false;

    /* Make sure any specified blend color space is valid along with other cond */
    if (code == 0 && dev_profile->blend_profile != NULL && !use_pdf14_accum) {
        if (!dev_profile->blend_profile->isdevlink &&
            !dev_profile->blend_profile->islab &&
            (dev_profile->blend_profile->data_cs == gsGRAY ||
             dev_profile->blend_profile->data_cs == gsRGB ||
             dev_profile->blend_profile->data_cs == gsCMYK)) {
            /* Also, do not allow the use of the blend space when we are pushing
               a pattern pdf14 device.  Those should inherit from the parent */
            if (!(gx_device_is_pattern_clist(pdev) ||
                  gx_device_is_pattern_accum(pdev))) {
                valid_blend_cs = true;
            }
        }
    }

    /* If num components is one, just go ahead and use gray.  This avoids
       issues with additive/subtractive mono color devices  */
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
        pdev->color_info.num_components == 1) {
        /*
        * Note:  We do not allow the SeparationOrder device parameter for
        * additive devices.  Thus we always have 1 colorant for DeviceGray
        * and 3 colorants for DeviceRGB.
        */
        if (valid_blend_cs) {
            *using_blend_cs = true;
            switch (dev_profile->blend_profile->num_comps) {
            case 1:
                return PDF14_DeviceGray;
            case 3:
                return PDF14_DeviceRGB;
            case 4:
                return PDF14_DeviceCMYK;
            }
        }
        if (pdev->color_info.num_components == 1)
            return PDF14_DeviceGray;
        else
            return PDF14_DeviceRGB;
    } else {
        /*
         * Check if the device is CMYK only or CMYK plus spot colors. Note
         * the CMYK plus spot colors will not support the blend color space
         */
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
        return PDF14_DeviceCustom;
#endif
        /*
         * Count the number of CMYK process components supported by the output
         * device.
         */
        for (i = 0; i < 4; i++) {
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];

            output_comp_num = dev_proc(pdev, get_color_comp_index)
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE);
            if (output_comp_num >= 0) {
                num_cmyk++;
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
                    num_cmyk_used++;
            }
        }
        /*
         * Check if the device supports only CMYK.  Otherewise we assume that
         * the output device supports spot colors.  Note:  This algorithm can
         * be fooled if the SeparationOrder device parameter is being used by
         * the output device device to only select CMYK.
         */
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
            && pdev->color_info.max_components == 4) {
            if (valid_blend_cs) {
                *using_blend_cs = true;
                switch (dev_profile->blend_profile->num_comps) {
                case 1:
                    return PDF14_DeviceGray;
                case 3:
                    return PDF14_DeviceRGB;
                case 4:
                    return PDF14_DeviceCMYK;
                }
            }
            return PDF14_DeviceCMYK;
        }
        /*
         * Check if we should use the 'custom' PDF 1.4 compositor device.
         * This device is only needed for those devices which do not support
         * a basic CMYK process color model.
         */
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
        if (num_cmyk != 4)
            return PDF14_DeviceCustom;
#endif
        /*
         * Otherewise we use a CMYK plus spot colors for blending.
         */
        return PDF14_DeviceCMYKspot;
    }
}
