summaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2023-02-07 18:19:20 +0000
committerRobin Watts <Robin.Watts@artifex.com>2023-02-08 15:36:40 +0000
commiteecd33392f90b77853a0d2ba64d115eec34890a3 (patch)
tree64cf3732a9f975c7bb7a13a90145afb0eb3833d2 /base
parent71d572e6b72d209b99f34b311298d51eac32fbb1 (diff)
downloadghostpdl-eecd33392f90b77853a0d2ba64d115eec34890a3.tar.gz
Add "imagematrices_are_untrustworthy" to gs_data_image_t
The pdfwrite device can 'rewrite' the image matrixes in a particularly nasty way that is not easy to avoid. It does this to be able to capture images with masks of a different size. Unfortunately, this breaks any possibility of us using the imagematrix to figure out which source region of the image we actually need for clipping. Introduce a new flag to capture when this happens so we can avoid relying on an untrustworthy imagematrix.
Diffstat (limited to 'base')
-rw-r--r--base/gsiparam.h101
-rw-r--r--base/gximage.c4
-rw-r--r--base/gximage1.c3
-rw-r--r--base/gxipixel.c4
4 files changed, 105 insertions, 7 deletions
diff --git a/base/gsiparam.h b/base/gsiparam.h
index bcf65371f..3c776a719 100644
--- a/base/gsiparam.h
+++ b/base/gsiparam.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2023 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -73,7 +73,6 @@ typedef enum {
* how the data are actually supplied.
*/
#define gs_data_image_common\
- const gx_image_type_t *type;\
/*\
* Define the transformation from user space to image space.\
*/\
@@ -104,11 +103,107 @@ typedef enum {
/*\
* Define whether to smooth the image.\
*/\
- bool Interpolate
+ bool Interpolate;\
+ /* If set, then the imagematrices have been changed (currently\
+ * just by the pdfwrite device for the purposes of handling\
+ * type3 masked images), so we can't trust them for mapping\
+ * backwards for source clipping. */\
+ bool imagematrices_are_untrustworthy;\
+ /* Put the type field last. See why below.*/\
+ const gx_image_type_t *type
typedef struct gs_data_image_s {
gs_data_image_common;
} gs_data_image_t;
+/* Ghostscript uses macros to define 'extended' structures.
+ * Suppose we want to define a structure foo, that can be extended to
+ * bigger_foo (and then maybe even to even_bigger_foo). We first
+ * define a macro such as 'foo_common' that contains the fields for
+ * foo.
+ *
+ * #define foo_common \
+ * void *a;\
+ * int b
+ *
+ * Then we define foo in terms of this:
+ *
+ * typedef struct {
+ * foo_common;
+ * } foo;
+ *
+ * Then we can extend this to other types as follows:
+ *
+ * typedef struct {
+ * foo_common;
+ * int c;
+ * int d;
+ * } bigger_foo;
+ *
+ * Or we can use macros to use even further extension:
+ *
+ * #define bigger_foo_common \
+ * foo_common;\
+ * int c;\
+ * int d
+ *
+ * typedef struct {
+ * bigger_foo_common;
+ * } bigger_foo;
+ *
+ * and hence:
+ *
+ * typedef struct {
+ * bigger_foo_common;
+ * int e;
+ * } even_bigger_foo;
+ *
+ * On the whole, this works well, and avoids the extra layer of
+ * structure that would occur if we used the more usual structure
+ * definition way of working:
+ *
+ * typedef struct {
+ * void *a;
+ * int b;
+ * } foo;
+ *
+ * typedef struct {
+ * foo base;
+ * int c;
+ * int d;
+ * } bigger_foo;
+ *
+ * typedef struct {
+ * bigger_foo base;
+ * int e;
+ * } even_bigger_foo;
+ *
+ * In this formulation even_bigger_foo would need to access 'a' as
+ * base.base.a, whereas the ghostscript method can just use 'a'.
+ *
+ * Unfortunately, there is one drawback to this method, to do with
+ * structure packing in C. C likes structures to be easily used in
+ * arrays. Hence (in a 64bit build), foo will be 16 bytes, where
+ * the foo fields included at the start of bigger_foo will only
+ * take 12.
+ *
+ * This means that constructs such as:
+ *
+ * void simple(foo *a)
+ * {
+ * bigger_foo b;
+ * b.c = 1;
+ * *(foo *)b = *a;
+ * ...
+ * }
+ *
+ * where we attempt to initialise the 'foo' fields of a bigger_foo, b, by
+ * copying them from an existing 'foo', will corrupt b.c.
+ *
+ * To allow this idiom to work, we either need to ensure that the largest
+ * alignment object in the 'foo' fields comes last, or we need to introduce
+ * padding. The former is easier.
+ */
+
#define public_st_gs_data_image() /* in gximage.c */\
gs_public_st_simple(st_gs_data_image, gs_data_image_t,\
"gs_data_image_t")
diff --git a/base/gximage.c b/base/gximage.c
index 90a60f4bf..be599aca6 100644
--- a/base/gximage.c
+++ b/base/gximage.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2023 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -36,6 +36,7 @@ void
gs_image_common_t_init(gs_image_common_t * pic)
{
gs_make_identity(&pic->ImageMatrix);
+ pic->imagematrices_are_untrustworthy = false;
}
void
gs_data_image_t_init(gs_data_image_t * pim, int num_components)
@@ -53,6 +54,7 @@ gs_data_image_t_init(gs_data_image_t * pim, int num_components)
pim->Decode[i] = 1, pim->Decode[i + 1] = 0;
}
pim->Interpolate = false;
+ pim->imagematrices_are_untrustworthy = false;
}
void
gs_pixel_image_t_init(gs_pixel_image_t * pim,
diff --git a/base/gximage1.c b/base/gximage1.c
index 48d879e0d..6de770818 100644
--- a/base/gximage1.c
+++ b/base/gximage1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2022 Artifex Software, Inc.
+/* Copyright (C) 2001-2023 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -59,6 +59,7 @@ gs_image_t_init_adjust(gs_image_t * pim, gs_color_space * color_space,
pim->type = (pim->ImageMask ? &gs_image_type_mask1 : &gs_image_type_1);
pim->Alpha = gs_image_alpha_none;
pim->image_parent_type = gs_image_type1;
+ pim->imagematrices_are_untrustworthy = 0;
}
void
gs_image_t_init_mask_adjust(gs_image_t * pim, bool write_1s, bool adjust)
diff --git a/base/gxipixel.c b/base/gxipixel.c
index 8b81aaa56..26b4d7667 100644
--- a/base/gxipixel.c
+++ b/base/gxipixel.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2022 Artifex Software, Inc.
+/* Copyright (C) 2001-2023 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -432,7 +432,7 @@ gx_image_enum_begin(gx_device * dev, const gs_gstate * pgs,
}
/* Can we restrict the amount of image we need? */
- while (pcpath) /* So we can break out of it */
+ while (pcpath && !pim->imagematrices_are_untrustworthy) /* So we can break out of it */
{
gs_rect rect, rect_src;
gs_matrix mi;