diff options
author | Robin Watts <Robin.Watts@artifex.com> | 2023-02-07 18:19:20 +0000 |
---|---|---|
committer | Robin Watts <Robin.Watts@artifex.com> | 2023-02-08 15:36:40 +0000 |
commit | eecd33392f90b77853a0d2ba64d115eec34890a3 (patch) | |
tree | 64cf3732a9f975c7bb7a13a90145afb0eb3833d2 /base | |
parent | 71d572e6b72d209b99f34b311298d51eac32fbb1 (diff) | |
download | ghostpdl-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.h | 101 | ||||
-rw-r--r-- | base/gximage.c | 4 | ||||
-rw-r--r-- | base/gximage1.c | 3 | ||||
-rw-r--r-- | base/gxipixel.c | 4 |
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; |