summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/gdevoflt.c')
-rw-r--r--base/gdevoflt.c107
1 files changed, 95 insertions, 12 deletions
diff --git a/base/gdevoflt.c b/base/gdevoflt.c
index 98f16f49..ff9424c7 100644
--- a/base/gdevoflt.c
+++ b/base/gdevoflt.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2021 Artifex Software, Inc.
+/* Copyright (C) 2001-2022 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -32,8 +32,10 @@
#include "gdevprn.h"
#include "gdevp14.h" /* Needed to patch up the procs after compositor creation */
#include "gximage.h" /* For gx_image_enum */
+#include "gximag3x.h"
#include "gdevsclass.h"
#include "gdevoflt.h"
+#include "gximag3x.h"
int gs_is_pdf14trans_compositor(const gs_composite_t * pct);
@@ -110,6 +112,7 @@ obj_filter_initialize_device_procs(gx_device *dev)
set_dev_proc(dev, strip_copy_rop2, obj_filter_strip_copy_rop2);
set_dev_proc(dev, strip_tile_rect_devn, obj_filter_strip_tile_rect_devn);
set_dev_proc(dev, fill_stroke_path, obj_filter_fill_stroke_path);
+ set_dev_proc(dev, composite, default_subclass_composite_front);
}
const
@@ -219,8 +222,10 @@ int obj_filter_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles
typedef struct obj_filter_image_enum_s {
gx_image_enum_common;
- int y;
- int height;
+ int y, mask_y;
+ int height, mask_height;
+ int type;
+ int InterleaveType;
} obj_filter_image_enum;
gs_private_st_composite(st_obj_filter_image_enum, obj_filter_image_enum, "obj_filter_image_enum",
obj_filter_image_enum_enum_ptrs, obj_filter_image_enum_reloc_ptrs);
@@ -243,15 +248,25 @@ obj_filter_image_plane_data(gx_image_enum_common_t * info,
{
obj_filter_image_enum *pie = (obj_filter_image_enum *)info;
- if (height > pie->height - pie->y)
- height = pie->height - pie->y;
+ if (pie->type == 3 && pie->InterleaveType == interleave_separate_source) {
+ pie->y += height;
+ pie->mask_y += height;
+ *rows_used = height;
- pie->y += height;
- *rows_used = height;
+ if (pie->y < pie->height || pie->mask_y < pie->mask_height)
+ return 0;
+ return 1;
+ } else {
+ if (height > pie->height - pie->y)
+ height = pie->height - pie->y;
+
+ pie->y += height;
+ *rows_used = height;
- if (pie->y < pie->height)
- return 0;
- return 1;
+ if (pie->y < pie->height)
+ return 0;
+ return 1;
+ }
}
static int
@@ -299,8 +314,76 @@ int obj_filter_begin_typed_image(gx_device *dev, const gs_gstate *pgs, const gs_
pie->memory = memory;
pie->skipping = true;
pie->height = pim->Height;
- pie->y = 0;
-
+ pie->mask_y = pie->y = 0;
+ pie->type = pic->type->index;
+
+ if (pic->type->index == 3) {
+ const gs_image3_t *pim = (const gs_image3_t *)pic;
+
+ switch (pim->InterleaveType)
+ {
+ case interleave_chunky:
+ /* Add the mask data to the depth of the image data. */
+ pie->num_planes = 1;
+ break;
+ case interleave_scan_lines:
+ /*
+ * There is only 1 plane, with dynamically changing width & depth.
+ * Initialize it for the mask data, since that is what will be
+ * read first.
+ */
+ pie->num_planes = 1;
+ pie->plane_depths[0] = 1;
+ pie->plane_widths[0] = pim->MaskDict.Width;
+ break;
+ case interleave_separate_source:
+ /* Insert the mask data as a separate plane before the image data. */
+ pie->num_planes = 2;
+ pie->plane_depths[1] = pie->plane_depths[0];
+ pie->plane_widths[1] = pie->plane_widths[0];
+ pie->plane_widths[0] = pim->MaskDict.Width;
+ pie->plane_depths[0] = 1;
+ pie->mask_height = pim->MaskDict.Height;
+ break;
+ }
+ pie->InterleaveType = pim->InterleaveType;
+ }
+ if (pic->type->index == IMAGE3X_IMAGETYPE) {
+ const gs_image3x_t *pim = (const gs_image3x_t *)pic;
+
+ if (pim->Opacity.MaskDict.BitsPerComponent != 0) {
+ switch(pim->Opacity.InterleaveType) {
+ case interleave_separate_source:
+ pie->num_planes++;
+ pie->plane_depths[1] = pie->plane_depths[0];
+ pie->plane_widths[1] = pie->plane_widths[0];
+ pie->plane_depths[0] = pim->Opacity.MaskDict.BitsPerComponent;
+ pie->plane_widths[0] = pim->Opacity.MaskDict.Width;
+ break;
+ case interleave_chunky:
+ pie->plane_depths[0] += pim->BitsPerComponent;
+ break;
+ default: /* can't happen */
+ return_error(gs_error_Fatal);
+ }
+ }
+ if (pim->Shape.MaskDict.BitsPerComponent != 0) {
+ switch(pim->Shape.InterleaveType) {
+ case interleave_separate_source:
+ pie->num_planes++;
+ pie->plane_depths[1] = pie->plane_depths[0];
+ pie->plane_widths[1] = pie->plane_widths[0];
+ pie->plane_depths[0] = pim->Shape.MaskDict.BitsPerComponent;
+ pie->plane_widths[0] = pim->Shape.MaskDict.Width;
+ break;
+ case interleave_chunky:
+ pie->plane_depths[0] += pim->BitsPerComponent;
+ break;
+ default: /* can't happen */
+ return_error(gs_error_Fatal);
+ }
+ }
+ }
return 0;
}