summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Deutschmann <whissi@gentoo.org>2019-10-15 12:24:12 +0200
committerThomas Deutschmann <whissi@gentoo.org>2020-08-13 11:26:55 +0200
commite088156d5b620e5e639580dacf85c6dc13823c74 (patch)
tree57f5c025e203279944da512166c20bc0521d8ccd /base/gximage1.c
downloadghostscript-gpl-patches-e088156d5b620e5e639580dacf85c6dc13823c74.tar.gz
ghostscript-gpl-patches-e088156d5b620e5e639580dacf85c6dc13823c74.tar.bz2
ghostscript-gpl-patches-e088156d5b620e5e639580dacf85c6dc13823c74.zip
Import Ghostscript 9.50ghostscript-9.50
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
Diffstat (limited to 'base/gximage1.c')
-rw-r--r--base/gximage1.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/base/gximage1.c b/base/gximage1.c
new file mode 100644
index 00000000..87d1e3e0
--- /dev/null
+++ b/base/gximage1.c
@@ -0,0 +1,239 @@
+/* Copyright (C) 2001-2019 Artifex Software, Inc.
+ All Rights Reserved.
+
+ This software is provided AS-IS with no warranty, either express or
+ implied.
+
+ This software is distributed under license and may not be copied,
+ modified or distributed except as expressly authorized under the terms
+ of the license contained in the file LICENSE in this distribution.
+
+ Refer to licensing information at http://www.artifex.com or contact
+ Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
+ CA 94945, U.S.A., +1(415)492-9861, for further information.
+*/
+
+
+/* ImageType 1 initialization */
+#include "gx.h"
+#include "gserrors.h"
+#include "gxiparam.h"
+#include "gximage.h"
+#include "stream.h"
+#include "memory_.h"
+
+/* Structure descriptor */
+public_st_gs_image1();
+
+/*
+ * Define the image types for ImageType 1 images.
+ * Note that opaque images and masks have different types, although
+ * they have the same ImageType.
+ */
+static image_proc_sput(gx_image1_sput);
+static image_proc_sget(gx_image1_sget);
+static image_proc_release(gx_image1_release);
+const gx_image_type_t gs_image_type_1 = {
+ &st_gs_image1, gx_begin_image1, gx_data_image_source_size,
+ gx_image1_sput, gx_image1_sget, gx_image1_release, 1
+};
+static image_proc_sput(gx_image1_mask_sput);
+static image_proc_sget(gx_image1_mask_sget);
+/*
+ * Image masks are not actually pixel images, so they don't need to
+ * worry about releasing the color space.
+ */
+const gx_image_type_t gs_image_type_mask1 = {
+ &st_gs_image1, gx_begin_image1, gx_data_image_source_size,
+ gx_image1_mask_sput, gx_image1_mask_sget, gx_image_default_release, 1
+};
+
+/* Define the procedures for initializing gs_image_ts to default values. */
+void
+gs_image_t_init_adjust(gs_image_t * pim, gs_color_space * color_space,
+ bool adjust)
+{
+ gs_pixel_image_t_init((gs_pixel_image_t *) pim, color_space);
+ pim->ImageMask = (color_space == NULL);
+ pim->adjust = adjust;
+ 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;
+}
+void
+gs_image_t_init_mask_adjust(gs_image_t * pim, bool write_1s, bool adjust)
+{
+ gs_image_t_init(pim, NULL);
+ if (write_1s)
+ pim->Decode[0] = 1, pim->Decode[1] = 0;
+ else
+ pim->Decode[0] = 0, pim->Decode[1] = 1;
+ pim->adjust = adjust;
+}
+
+/* Start processing an ImageType 1 image. */
+int
+gx_begin_image1(gx_device * dev,
+ const gs_gstate * pgs, const gs_matrix * pmat,
+ const gs_image_common_t * pic, const gs_int_rect * prect,
+ const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
+ gs_memory_t * mem, gx_image_enum_common_t ** pinfo)
+{
+ gx_image_enum *penum;
+ const gs_image_t *pim = (const gs_image_t *)pic;
+ int code = gx_image_enum_alloc(pic, prect, mem, &penum);
+
+ if (code < 0)
+ return code;
+ penum->alpha = pim->Alpha;
+ penum->use_mask_color = false;
+ penum->image_parent_type = pim->image_parent_type;
+ penum->masked = pim->ImageMask;
+ penum->adjust =
+ (pim->ImageMask && pim->adjust ? float2fixed(0.25) : fixed_0);
+ code = gx_image_enum_begin(dev, pgs, pmat, pic, pdcolor, pcpath, mem,
+ penum);
+ if (code >= 0)
+ *pinfo = (gx_image_enum_common_t *)penum;
+ else {
+ *pinfo = NULL;
+ }
+ return code;
+}
+
+/* Serialization */
+
+/*
+ * We add the Alpha value to the control word.
+ */
+
+static int
+gx_image1_sput(const gs_image_common_t *pic, stream *s,
+ const gs_color_space **ppcs)
+{
+ const gs_image_t *const pim = (const gs_image_t *)pic;
+
+ return gx_pixel_image_sput((const gs_pixel_image_t *)pic, s, ppcs,
+ (int)pim->Alpha);
+}
+
+static int
+gx_image1_sget(gs_image_common_t *pic, stream *s,
+ gs_color_space *pcs)
+{
+ gs_image1_t *const pim = (gs_image1_t *)pic;
+ int code = gx_pixel_image_sget((gs_pixel_image_t *)pim, s, pcs);
+
+ if (code < 0)
+ return code;
+ pim->type = &gs_image_type_1;
+ pim->ImageMask = false;
+ pim->Alpha = code;
+ pim->image_parent_type = gs_image_type1;
+ return 0;
+}
+
+/*
+ * Masks have different parameters, so we use a different encoding:
+ * FFFFEEDCBA
+ * A = 0 if standard ImageMatrix, 1 if explicit ImageMatrix
+ * B = 0 if Decode=[0 1], 1 if Decode=[1 0]
+ * C = Interpolate
+ * D = adjust
+ * EE = Alpha
+ * FFFF = BitsPerComponent - 1 (only needed for soft masks)
+ * Width, encoded as a variable-length uint
+ * Height, encoded like Width
+ * ImageMatrix (if A = 1), per gs_matrix_store/fetch
+ */
+#define MI_ImageMatrix 0x01
+#define MI_Decode 0x02
+#define MI_Interpolate 0x04
+#define MI_adjust 0x08
+#define MI_Alpha_SHIFT 4
+#define MI_Alpha_MASK 0x3
+#define MI_BPC_SHIFT 6
+#define MI_BPC_MASK 0xf
+#define MI_BITS 10
+
+static int
+gx_image1_mask_sput(const gs_image_common_t *pic, stream *s,
+ const gs_color_space **ignore_ppcs)
+{
+ const gs_image_t *pim = (const gs_image_t *)pic;
+ uint control =
+ (gx_image_matrix_is_default((const gs_data_image_t *)pim) ? 0 :
+ MI_ImageMatrix) |
+ (pim->Decode[0] != 0 ? MI_Decode : 0) |
+ (pim->Interpolate ? MI_Interpolate : 0) |
+ (pim->adjust ? MI_adjust : 0) |
+ (pim->Alpha << MI_Alpha_SHIFT) |
+ ((pim->BitsPerComponent - 1) << MI_BPC_SHIFT);
+
+ sput_variable_uint(s, control);
+ sput_variable_uint(s, (uint)pim->Width);
+ sput_variable_uint(s, (uint)pim->Height);
+ if (control & MI_ImageMatrix)
+ sput_matrix(s, &pim->ImageMatrix);
+ return 0;
+}
+
+static int
+gx_image1_mask_sget(gs_image_common_t *pic, stream *s,
+ gs_color_space *ignore_pcs)
+{
+ gs_image1_t *const pim = (gs_image1_t *)pic;
+ int code;
+ uint control;
+
+ if ((code = sget_variable_uint(s, &control)) < 0)
+ return code;
+ gs_image_t_init_mask(pim, (control & MI_Decode) != 0);
+ if ((code = sget_variable_uint(s, (uint *)&pim->Width)) < 0 ||
+ (code = sget_variable_uint(s, (uint *)&pim->Height)) < 0
+ )
+ return code;
+ if (control & MI_ImageMatrix) {
+ if ((code = sget_matrix(s, &pim->ImageMatrix)) < 0)
+ return code;
+ } else
+ gx_image_matrix_set_default((gs_data_image_t *)pim);
+ pim->Interpolate = (control & MI_Interpolate) != 0;
+ pim->adjust = (control & MI_adjust) != 0;
+ pim->Alpha = (control >> MI_Alpha_SHIFT) & MI_Alpha_MASK;
+ pim->BitsPerComponent = ((control >> MI_BPC_SHIFT) & MI_BPC_MASK) + 1;
+ return 0;
+}
+
+static void
+gx_image1_release(gs_image_common_t *pic, gs_memory_t *mem)
+{
+ gx_pixel_image_release((gs_pixel_image_t *)pic, mem);
+}
+
+/* Free the image enumerator. */
+void
+gx_image_free_enum(gx_image_enum_common_t **ppenum)
+{
+ gx_image_enum_common_t * penum = *ppenum;
+ gs_memory_t *mem = penum->memory;
+
+ /* Bug 688845 comment #38 :
+ Adobe Illustrator creates a Postscript document,
+ in which an image data procedure executes 'save',
+ and the corresponding 'restore' appears after the image end.
+ It causes this procedure is called at a higher save level than
+ at which the enumerator was allocated, so that gs_free_object below
+ works idle. Nevertheless we can't leave pointers in the structure,
+ because they may point to blocks already released
+ by the client's subclass method for end_image.
+ Leaving them uncleaned caused a real crash in the garbager - see bug 688845.
+ So we clean the entire subclassed enumerator here,
+ rather this is a generic function for base class.
+ Note the cleaning is neccessaryfor Postscript only,
+ because other languaged don't implement save-restore.
+ */
+ memset(penum, 0, gs_object_size(mem, penum));
+ gs_free_object(mem, penum, "gx_image_free_enum");
+ *ppenum = NULL;
+}