summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNancy Durgin <nancy.durgin@artifex.com>2020-02-13 14:48:05 -0800
committerChris Liddell <chris.liddell@artifex.com>2020-02-26 08:18:49 +0000
commit25cd0c72b98f9efc6968254d1e3a2f33ec376369 (patch)
tree452763260d26e3f62c3a992558c89b9f3452f4c2
parente9523603ac713e365702b81c228edcaaac667dc4 (diff)
downloadghostpdl-25cd0c72b98f9efc6968254d1e3a2f33ec376369.tar.gz
Bug701972 -- fix pdfwrite image downscaling bug
Calculate the bits on the row using the input image width, not the output image width. I had to add an extra argument to a few functions to propagate the info down to where it is needed. Note obscure case involving calling psdf_setup_image_to_mask_filter() for a Type 4 image and CompatibilityLevel < 1.3. This change just adds the extra input_width arg, which doesn't change whatever it was doing before. If there is a bug lurking here, it seems unlikely anybody cares?
-rw-r--r--devices/vector/gdevpdfi.c12
-rw-r--r--devices/vector/gdevpsdf.h7
-rw-r--r--devices/vector/gdevpsdi.c15
-rw-r--r--devices/vector/gdevpsds.c5
-rw-r--r--devices/vector/gdevpsds.h3
5 files changed, 27 insertions, 15 deletions
diff --git a/devices/vector/gdevpdfi.c b/devices/vector/gdevpdfi.c
index d415cbacc..b73ed3d66 100644
--- a/devices/vector/gdevpdfi.c
+++ b/devices/vector/gdevpdfi.c
@@ -1511,7 +1511,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
image[0].pixel.ColorSpace = pcs_orig;
image[0].pixel.BitsPerComponent = pim->BitsPerComponent;
code = psdf_setup_image_colors_filter(&pie->writer.binary[0],
- (gx_device_psdf *)pdev, &image[0].pixel, pgs);
+ (gx_device_psdf *)pdev, pim, &image[0].pixel, pgs);
if (code < 0)
goto fail_and_fallback;
image[0].pixel.ColorSpace = pcs_device;
@@ -1558,7 +1558,7 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
image[1].pixel.ColorSpace = pcs_orig;
image[1].pixel.BitsPerComponent = pim->BitsPerComponent;
code = psdf_setup_image_colors_filter(&pie->writer.binary[1],
- (gx_device_psdf *)pdev, &image[1].pixel, pgs);
+ (gx_device_psdf *)pdev, pim, &image[1].pixel, pgs);
if (code < 0) {
goto fail_and_fallback;
}
@@ -1596,9 +1596,13 @@ pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
pmat, pgs, force_lossless, in_line);
if (code < 0)
goto fail_and_fallback;
+ /* Bug701972 -- added input_width arg here. For this case, just passing in the same
+ * width as before, so nothing changes. This is an obscure case that isn't tested
+ * on the cluster (note that it requires CompatibilityLevel < 1.3).
+ */
psdf_setup_image_to_mask_filter(&pie->writer.binary[i],
- (gx_device_psdf *)pdev, pim->Width, pim->Height,
- num_components, pim->BitsPerComponent, image[i].type4.MaskColor);
+ (gx_device_psdf *)pdev, pim->Width, pim->Height, pim->Width,
+ num_components, pim->BitsPerComponent, image[i].type4.MaskColor);
code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
&image[i].pixel, &cs_value, pie);
if (code < 0)
diff --git a/devices/vector/gdevpsdf.h b/devices/vector/gdevpsdf.h
index 959a41437..5047f43a1 100644
--- a/devices/vector/gdevpsdf.h
+++ b/devices/vector/gdevpsdf.h
@@ -459,11 +459,14 @@ int psdf_setup_compression_chooser(psdf_binary_writer *pbw,
/* Set up an "image to mask" filter. */
int psdf_setup_image_to_mask_filter(psdf_binary_writer *pbw, gx_device_psdf *pdev,
- int width, int height, int depth, int bits_per_sample, uint *MaskColor);
+ int width, int height, int input_width,
+ int depth, int bits_per_sample, uint *MaskColor);
/* 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,
+ gx_device_psdf *pdev,
+ const gs_pixel_image_t *input_pim,
+ gs_pixel_image_t * pim,
const gs_gstate *pgs);
/* ---------------- Symbolic data printing ---------------- */
diff --git a/devices/vector/gdevpsdi.c b/devices/vector/gdevpsdi.c
index 485d685ae..9c2adb724 100644
--- a/devices/vector/gdevpsdi.c
+++ b/devices/vector/gdevpsdi.c
@@ -828,7 +828,8 @@ psdf_setup_compression_chooser(psdf_binary_writer *pbw, gx_device_psdf *pdev,
/* Set up an "image to mask" filter. */
int
psdf_setup_image_to_mask_filter(psdf_binary_writer *pbw, gx_device_psdf *pdev,
- int width, int height, int depth, int bits_per_sample, uint *MaskColor)
+ int width, int height, int input_width,
+ int depth, int bits_per_sample, uint *MaskColor)
{
int code;
stream_state *ss = s_alloc_state(pdev->memory, s__image_colors_template.stype,
@@ -842,7 +843,7 @@ psdf_setup_image_to_mask_filter(psdf_binary_writer *pbw, gx_device_psdf *pdev,
if (code < 0)
return code;
s_image_colors_set_dimensions((stream_image_colors_state *)ss,
- width, height, depth, bits_per_sample);
+ width, height, input_width, depth, bits_per_sample);
s_image_colors_set_mask_colors((stream_image_colors_state *)ss, MaskColor);
return 0;
}
@@ -850,7 +851,9 @@ psdf_setup_image_to_mask_filter(psdf_binary_writer *pbw, gx_device_psdf *pdev,
/* 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,
+ gx_device_psdf *pdev,
+ const gs_pixel_image_t *input_pim,
+ gs_pixel_image_t * pim,
const gs_gstate *pgs)
{ /* fixme: currently it's a stub convertion to mask. */
int code;
@@ -866,9 +869,9 @@ psdf_setup_image_colors_filter(psdf_binary_writer *pbw,
if (code < 0)
return code;
s_image_colors_set_dimensions((stream_image_colors_state *)ss,
- pim->Width, pim->Height,
- gs_color_space_num_components(pim->ColorSpace),
- pim->BitsPerComponent);
+ pim->Width, pim->Height, input_pim->Width,
+ gs_color_space_num_components(pim->ColorSpace),
+ pim->BitsPerComponent);
s_image_colors_set_color_space((stream_image_colors_state *)ss,
(gx_device *)pdev, pim->ColorSpace, pgs, pim->Decode);
pim->BitsPerComponent = pdev->color_info.comp_bits[0]; /* Same precision for all components. */
diff --git a/devices/vector/gdevpsds.c b/devices/vector/gdevpsds.c
index 44ba2b4c1..65bbf544d 100644
--- a/devices/vector/gdevpsds.c
+++ b/devices/vector/gdevpsds.c
@@ -1248,13 +1248,14 @@ s_image_colors_set_mask_colors(stream_image_colors_state * ss, uint *MaskColor)
/* Set image dimensions. */
void
s_image_colors_set_dimensions(stream_image_colors_state * ss,
- int width, int height, int depth, int bits_per_sample)
+ int width, int height, int input_width,
+ int depth, int bits_per_sample)
{
ss->width = width;
ss->height = height;
ss->depth = depth;
ss->bits_per_sample = bits_per_sample;
- ss->row_bits = bits_per_sample * depth * width;
+ ss->row_bits = bits_per_sample * depth * input_width;
ss->raster = bitmap_raster(ss->row_bits);
ss->row_alignment_bytes = 0; /* (ss->raster * 8 - ss->row_bits) / 8) doesn't work. */
}
diff --git a/devices/vector/gdevpsds.h b/devices/vector/gdevpsds.h
index 310072ce5..35a756f0f 100644
--- a/devices/vector/gdevpsds.h
+++ b/devices/vector/gdevpsds.h
@@ -253,7 +253,8 @@ struct stream_image_transfer_state_s {
stream_image_colors_reloc_ptrs, pcs, pdev, pgs)
void s_image_colors_set_dimensions(stream_image_colors_state * st,
- int width, int height, int depth, int bits_per_sample);
+ int width, int height, int input_width,
+ int depth, int bits_per_sample);
void s_image_colors_set_mask_colors(stream_image_colors_state * ss, uint *MaskColor);