summaryrefslogtreecommitdiff
path: root/gs
diff options
context:
space:
mode:
authorIgor Melichev <igor.melichev@artifex.com>2006-03-09 10:54:46 +0000
committerIgor Melichev <igor.melichev@artifex.com>2006-03-09 10:54:46 +0000
commit0d55e63745c3aa397a72471379d936346ceb5d1d (patch)
tree7cf043c6c272b71a3d8799506f55a09f233437fc /gs
parente46574e9747b1c00296070425d61fb657e1f0fd7 (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.htm2
-rw-r--r--gs/src/gdevpdfi.c115
-rw-r--r--gs/src/gdevpsdf.h3
-rw-r--r--gs/src/gdevpsdi.c29
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;
}