/* Create a Separation or DeviceN color space (internal). */
static int
pdf_separation_color_space(gx_device_pdf *pdev,
			   cos_array_t *pca, const char *csname,
			   const cos_value_t *snames,
			   const gs_color_space *alt_space,
			   const gs_function_t *pfn,
			   const pdf_color_space_names_t *pcsn,
			   const cos_value_t *v_attributes)
{
    cos_value_t v;
    const gs_range_t *ranges;
    int code;

    if ((code = cos_array_add(pca, cos_c_string_value(&v, csname))) < 0 ||
	(code = cos_array_add_no_copy(pca, snames)) < 0 ||
	(code = pdf_color_space(pdev, &v, &ranges, alt_space, pcsn, false)) < 0 ||
	(code = cos_array_add(pca, &v)) < 0 ||
	(code = pdf_function_scaled(pdev, pfn, ranges, &v)) < 0 ||
	(code = cos_array_add(pca, &v)) < 0 ||
	(v_attributes != NULL ? code = cos_array_add(pca, v_attributes) : 0) < 0
	)
	return code;
    return 0;
}
Exemple #2
0
/* Create a Separation or DeviceN color space (internal). */
static int
pdf_separation_color_space(gx_device_pdf *pdev,
                           cos_array_t *pca, const char *csname,
                           const cos_value_t *snames,
                           const gs_color_space *alt_space,
                           const gs_function_t *pfn,
                           const pdf_color_space_names_t *pcsn,
                           const cos_value_t *v_attributes)
{
    cos_value_t v;
    const gs_range_t *ranges;
    int code, csi;

    /* We need to think about the alternate space. If we are producing
     * PDF/X or PDF/A we can't produce some device spaces, and the code in
     * pdf_color_space_named always allows device spaces. We could alter
     * that code, but by then we don't know its an Alternate space, and have
     * lost the tin transform procedure. So instead we check here.
     */
    csi = gs_color_space_get_index(alt_space);
    /* Note that if csi is ICC, check to see if this was one of
       the default substitutes that we introduced for DeviceGray,
       DeviceRGB or DeviceCMYK.  If it is, then just write
       the default color.  Depending upon the flavor of PDF,
       or other options, we may want to actually have all
       the colors defined by ICC profiles and not do the following
       substituion of the Device space. */
    if (csi == gs_color_space_index_ICC) {
        csi = gsicc_get_default_type(alt_space->cmm_icc_profile_data);
    }
    if (csi == gs_color_space_index_DeviceRGB && (pdev->PDFX ||
            (pdev->PDFA && (pdev->pcm_color_info_index == gs_color_space_index_DeviceCMYK)))) {

        /* We have a DeviceRGB alternate, but are producing either PDF/X or
         * PDF/A with a DeviceCMYK process color model. So we need to convert
         * the alternate space into CMYK. We do this by evaluating the function
         * at each end of the Separation space (0 and 1), convert the resulting
         * RGB colours into CMYK and create a new function which linearly
         * interpolates between these points.
         */
        gs_function_t *new_pfn = 0;
        float in[1] = {0.0f};
        float out_low[4];
        float out_high[4];

        code = gs_function_evaluate(pfn, in, out_low);
        if (code < 0)
            return code;
        pdf_SepRGB_ConvertToCMYK((float *)&out_low, (float *)&out_low);

        in[0] = 1.0f;
        code = gs_function_evaluate(pfn, in, out_high);
        if (code < 0)
            return code;
        pdf_SepRGB_ConvertToCMYK((float *)&out_high, (float *)&out_high);

        code = pdf_make_base_space_function(pdev, &new_pfn, 4, out_low, out_high);
        if (code < 0)
            return code;
        if ((code = cos_array_add(pca, cos_c_string_value(&v, csname))) < 0 ||
                (code = cos_array_add_no_copy(pca, snames)) < 0 ||
                (code = (int)cos_c_string_value(&v, (const char *)pcsn->DeviceCMYK)) < 0 ||
                (code = cos_array_add(pca, &v)) < 0 ||
                (code = pdf_function_scaled(pdev, new_pfn, 0x00, &v)) < 0 ||
                (code = cos_array_add(pca, &v)) < 0 ||
                (v_attributes != NULL ? code = cos_array_add(pca, v_attributes) : 0) < 0
           ) {}
        pdf_delete_base_space_function(pdev, new_pfn);
        return code;
    }
    if (csi == gs_color_space_index_DeviceCMYK &&
            (pdev->PDFA && (pdev->pcm_color_info_index == gs_color_space_index_DeviceRGB))) {
        /* We have a DeviceCMYK alternate, but are producingPDF/A with a
         * DeviceRGB process color model. See comment above re DviceRGB.
         */
        gs_function_t *new_pfn = 0;
        float in[1] = {0.0f};
        float out_low[4];
        float out_high[4];

        code = gs_function_evaluate(pfn, in, out_low);
        if (code < 0)
            return code;
        pdf_SepCMYK_ConvertToRGB((float *)&out_low, (float *)&out_low);

        in[0] = 1.0f;
        code = gs_function_evaluate(pfn, in, out_high);
        if (code < 0)
            return code;
        pdf_SepCMYK_ConvertToRGB((float *)&out_high, (float *)&out_high);

        code = pdf_make_base_space_function(pdev, &new_pfn, 3, out_low, out_high);
        if (code < 0)
            return code;
        if ((code = cos_array_add(pca, cos_c_string_value(&v, csname))) < 0 ||
                (code = cos_array_add_no_copy(pca, snames)) < 0 ||
                (code = (int)cos_c_string_value(&v, pcsn->DeviceRGB)) < 0 ||
                (code = cos_array_add(pca, &v)) < 0 ||
                (code = pdf_function_scaled(pdev, new_pfn, 0x00, &v)) < 0 ||
                (code = cos_array_add(pca, &v)) < 0 ||
                (v_attributes != NULL ? code = cos_array_add(pca, v_attributes) : 0) < 0
           ) {}
        pdf_delete_base_space_function(pdev, new_pfn);
        return code;
    }

    if ((code = cos_array_add(pca, cos_c_string_value(&v, csname))) < 0 ||
            (code = cos_array_add_no_copy(pca, snames)) < 0 ||
            (code = pdf_color_space_named(pdev, &v, &ranges, alt_space, pcsn, false, NULL, 0)) < 0 ||
            (code = cos_array_add(pca, &v)) < 0 ||
            (code = pdf_function_scaled(pdev, pfn, ranges, &v)) < 0 ||
            (code = cos_array_add(pca, &v)) < 0 ||
            (v_attributes != NULL ? code = cos_array_add(pca, v_attributes) : 0) < 0
       )
        return code;
    return 0;
}