diff options
author | Igor Melichev <igor.melichev@artifex.com> | 2006-03-09 10:54:46 +0000 |
---|---|---|
committer | Igor Melichev <igor.melichev@artifex.com> | 2006-03-09 10:54:46 +0000 |
commit | 0d55e63745c3aa397a72471379d936346ceb5d1d (patch) | |
tree | 7cf043c6c272b71a3d8799506f55a09f233437fc /gs | |
parent | e46574e9747b1c00296070425d61fb657e1f0fd7 (diff) |
pdfwrite : A simplified implementation for ColorConversionStrategy, continued 2.
DETAILS :
This implements color conversion for images.
1. make_device_color_space is factored out from psdf_setup_image_colors_filter,
because the substituted color spase is needed for pdf_begin_write_image,
which works before installing the image colors filter.
2. In pdf_begin_typed_image the new variables pcs_device and pcs_orig
provide a right logics for the color space substitution.
EXPECTED DIFFERENCES :
None.
git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@6640 a1074d23-0009-0410-80fe-cf8c14f379e6
Diffstat (limited to 'gs')
-rw-r--r-- | gs/doc/Ps2pdf.htm | 2 | ||||
-rw-r--r-- | gs/src/gdevpdfi.c | 115 | ||||
-rw-r--r-- | gs/src/gdevpsdf.h | 3 | ||||
-rw-r--r-- | gs/src/gdevpsdi.c | 29 |
4 files changed, 101 insertions, 48 deletions
diff --git a/gs/doc/Ps2pdf.htm b/gs/doc/Ps2pdf.htm index 875005891..f19c0b19c 100644 --- a/gs/doc/Ps2pdf.htm +++ b/gs/doc/Ps2pdf.htm @@ -582,7 +582,7 @@ The value <tt><b>CMYK</tt></b> works with any <tt><b>CompatibilityLevel</tt></b> requires the device parameter <tt><b>ProcessColorModel</tt></b> to be set to <tt><b>DeviceCMYK</tt></b>. The value <tt><b>sRGB</tt></b> requires the device parameter <tt><b>ProcessColorModel</tt></b> to be set to <tt><b>DeviceRGB</tt></b>, -and actually converts to RBG with the default Ghostscript conversion. +and actually converts to RGB with the default Ghostscript conversion. The new Ghostscript-specific value <tt><b>Gray</tt></b> requires the device parameter <tt><b>ProcessColorModel</tt></b> to be set to <tt><b>DeviceGray</tt></b>, and converts all colors to DeviceGray. diff --git a/gs/src/gdevpdfi.c b/gs/src/gdevpdfi.c index 862c6a570..76beca8d3 100644 --- a/gs/src/gdevpdfi.c +++ b/gs/src/gdevpdfi.c @@ -238,6 +238,51 @@ pdf_begin_image_data_decoded(gx_device_pdf *pdev, int num_components, const gs_r return pdf_begin_image_data(pdev, &pie->writer, pi, cs_value, i); } +private int +make_device_color_space(gx_device_pdf *pdev, + gs_color_space_index output_cspace_index, + gs_color_space **ppcs) +{ + gs_color_space *cs; + gs_memory_t *mem = pdev->v_memory; + + cs = gs_alloc_struct(mem, gs_color_space, &st_color_space, + "psdf_setup_image_colors_filter"); + if (cs == NULL) + return_error(gs_error_VMerror); + switch (output_cspace_index) { + case gs_color_space_index_DeviceGray: + gs_cspace_init_DeviceGray(mem, cs); + break; + case gs_color_space_index_DeviceRGB: + gs_cspace_init_DeviceRGB(mem, cs); + break; + case gs_color_space_index_DeviceCMYK: + gs_cspace_init_DeviceCMYK(mem, cs); + break; + default: + /* Notify the user and terminate. + Don't emit rangecheck becuause it would fall back + to a default implementation (rasterisation). + */ + eprintf("Unsupported ProcessColorModel"); + return_error(gs_error_undefined); + } + *ppcs = cs; + return 0; +} + +private bool +check_image_color_space(gs_pixel_image_t * pim, gs_color_space_index index) +{ + if (pim->ColorSpace->type->index == index) + return true; + if (pim->ColorSpace->type->index == gs_color_space_index_Indexed) + if (pim->ColorSpace->params.indexed.base_space.type->index == index) + return true; + return false; +} + /* * Start processing an image. This procedure takes extra arguments because * it has to do something slightly different for the parts of an ImageType 3 @@ -284,6 +329,8 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis, const gs_range_t *pranges = 0; const pdf_color_space_names_t *names; bool convert_to_process_colors = false; + gs_color_space *pcs_device = NULL; + const gs_color_space *pcs_orig = NULL; pdf_lcvd_t *cvd = NULL; /* @@ -583,22 +630,52 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis, code = pdf_color_space(pdev, &cs_value, &pranges, pcs, names, in_line); - if (code < 0) { - const char *sname; - + if (code < 0) convert_to_process_colors = true; - switch (pdev->pcm_color_info_index) { - case gs_color_space_index_DeviceGray: sname = names->DeviceGray; break; - case gs_color_space_index_DeviceRGB: sname = names->DeviceRGB; break; - case gs_color_space_index_DeviceCMYK: sname = names->DeviceCMYK; break; - default: - eprintf("Unsupported ProcessColorModel."); - return_error(gs_error_undefined); - } - cos_c_string_value(&cs_value, sname); - } } } + if ((pdev->params.ColorConversionStrategy == ccs_Gray && + !check_image_color_space(&image[0].pixel, gs_color_space_index_DeviceGray)) || + (pdev->params.ColorConversionStrategy == ccs_sRGB && + !psdf_is_converting_image_to_RGB((const gx_device_psdf *)pdev, pis, &image[0].pixel) && + !check_image_color_space(&image[0].pixel, gs_color_space_index_DeviceGray) && + !check_image_color_space(&image[0].pixel, gs_color_space_index_DeviceRGB)) || + (pdev->params.ColorConversionStrategy == ccs_CMYK && + !check_image_color_space(&image[0].pixel, gs_color_space_index_DeviceGray) && + !check_image_color_space(&image[0].pixel, gs_color_space_index_DeviceCMYK))) { + /* fixme : as a rudiment of old code, + the case psdf_is_converting_image_to_RGB + is handled with the 'cmyk_to_rgb' branch + in psdf_setup_image_filters. */ + if ((pdev->params.ColorConversionStrategy == ccs_CMYK && + strcmp(pdev->color_info.cm_name, "DeviceCMYK")) || + (pdev->params.ColorConversionStrategy == ccs_sRGB && + strcmp(pdev->color_info.cm_name, "DeviceRGB")) || + (pdev->params.ColorConversionStrategy == ccs_Gray && + strcmp(pdev->color_info.cm_name, "DeviceGray"))) { + eprintf("ColorConversionStrategy isn't compatible to ProcessColorModel."); + return_error(gs_error_rangecheck); + } + convert_to_process_colors = true; + } + if (convert_to_process_colors) { + const char *sname; + + switch (pdev->pcm_color_info_index) { + case gs_color_space_index_DeviceGray: sname = names->DeviceGray; break; + case gs_color_space_index_DeviceRGB: sname = names->DeviceRGB; break; + case gs_color_space_index_DeviceCMYK: sname = names->DeviceCMYK; break; + default: + eprintf("Unsupported ProcessColorModel."); + return_error(gs_error_undefined); + } + cos_c_string_value(&cs_value, sname); + pcs_orig = image[0].pixel.ColorSpace; + code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device); + if (code < 0) + goto fail; + image[0].pixel.ColorSpace = pcs_device; + } if ((code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width, height, pnamed, in_line)) < 0 || /* @@ -620,16 +697,19 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis, ) goto fail; if (convert_to_process_colors) { + image[0].pixel.ColorSpace = pcs_orig; code = psdf_setup_image_colors_filter(&pie->writer.binary[0], - (gx_device_psdf *)pdev, &image[0].pixel, pis, - pdev->pcm_color_info_index); + (gx_device_psdf *)pdev, &image[0].pixel, pis); if (code < 0) goto fail; + image[0].pixel.ColorSpace = pcs_device; } if (pie->writer.alt_writer_count > 1) { code = pdf_make_alt_stream(pdev, &pie->writer.binary[1]); if (code) goto fail; + if (convert_to_process_colors) + image[1].pixel.ColorSpace = pcs_device; code = psdf_setup_image_filters((gx_device_psdf *) pdev, &pie->writer.binary[1], &image[1].pixel, pmat, pis, false); @@ -641,11 +721,12 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_imager_state * pis, } else if (code) goto fail; else if (convert_to_process_colors) { + image[1].pixel.ColorSpace = pcs_orig; code = psdf_setup_image_colors_filter(&pie->writer.binary[1], - (gx_device_psdf *)pdev, &image[1].pixel, pis, - pdev->pcm_color_info_index); + (gx_device_psdf *)pdev, &image[1].pixel, pis); if (code < 0) goto fail; + image[1].pixel.ColorSpace = pcs_device; } } for (i = 0; i < pie->writer.alt_writer_count; i++) { diff --git a/gs/src/gdevpsdf.h b/gs/src/gdevpsdf.h index d2c3517c1..d04b8c7bd 100644 --- a/gs/src/gdevpsdf.h +++ b/gs/src/gdevpsdf.h @@ -368,8 +368,7 @@ int psdf_setup_image_to_mask_filter(psdf_binary_writer *pbw, gx_device_psdf *pde /* Set up an image colors filter. */ int psdf_setup_image_colors_filter(psdf_binary_writer *pbw, gx_device_psdf *pdev, gs_pixel_image_t * pim, - const gs_imager_state *pis, - gs_color_space_index output_cspace_index); + const gs_imager_state *pis); /* ---------------- Symbolic data printing ---------------- */ diff --git a/gs/src/gdevpsdi.c b/gs/src/gdevpsdi.c index 8c14e1406..c4cf2d814 100644 --- a/gs/src/gdevpsdi.c +++ b/gs/src/gdevpsdi.c @@ -622,15 +622,11 @@ psdf_setup_image_to_mask_filter(psdf_binary_writer *pbw, gx_device_psdf *pdev, int psdf_setup_image_colors_filter(psdf_binary_writer *pbw, gx_device_psdf *pdev, gs_pixel_image_t * pim, - const gs_imager_state *pis, - gs_color_space_index output_cspace_index) + const gs_imager_state *pis) { /* fixme: currently it's a stub convertion to mask. */ int code; - extern_st(st_color_space); - gs_memory_t *mem = pdev->v_memory; stream_state *ss = s_alloc_state(pdev->memory, s__image_colors_template.stype, "psdf_setup_image_colors_filter"); - gs_color_space *cs; int i; if (ss == 0) @@ -640,10 +636,6 @@ psdf_setup_image_colors_filter(psdf_binary_writer *pbw, code = psdf_encode_binary(pbw, &s__image_colors_template, ss); if (code < 0) return code; - cs = gs_alloc_struct(mem, gs_color_space, &st_color_space, - "psdf_setup_image_colors_filter"); - if (cs == NULL) - return_error(gs_error_VMerror); s_image_colors_set_dimensions((stream_image_colors_state *)ss, pim->Width, pim->Height, gs_color_space_num_components(pim->ColorSpace), @@ -655,24 +647,5 @@ psdf_setup_image_colors_filter(psdf_binary_writer *pbw, pim->Decode[i * 2 + 0] = 0; pim->Decode[i * 2 + 1] = 1; } - switch (output_cspace_index) { - case gs_color_space_index_DeviceGray: - gs_cspace_init_DeviceGray(mem, cs); - break; - case gs_color_space_index_DeviceRGB: - gs_cspace_init_DeviceRGB(mem, cs); - break; - case gs_color_space_index_DeviceCMYK: - gs_cspace_init_DeviceCMYK(mem, cs); - break; - default: - /* Notify the user and terminate. - Don't emit rangecheck becuause it would fall back - to a default implementation (rasterisation). - */ - eprintf("Unsupported ProcessColorModel"); - return_error(gs_error_undefined); - } - pim->ColorSpace = cs; return 0; } |