summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'base/gdevmpla.c')
-rw-r--r--base/gdevmpla.c82
1 files changed, 79 insertions, 3 deletions
diff --git a/base/gdevmpla.c b/base/gdevmpla.c
index ae805f4e..d889efcf 100644
--- a/base/gdevmpla.c
+++ b/base/gdevmpla.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001-2019 Artifex Software, Inc.
+/* Copyright (C) 2001-2020 Artifex Software, Inc.
All Rights Reserved.
This software is provided AS-IS with no warranty, either express or
@@ -29,6 +29,7 @@
/* procedures */
static dev_proc_open_device(mem_planar_open);
+static dev_proc_open_device(mem_planar_open_interleaved);
declare_mem_procs(mem_planar_copy_mono, mem_planar_copy_color, mem_planar_fill_rectangle);
static dev_proc_copy_color(mem_planar_copy_color_24to8);
static dev_proc_copy_color(mem_planar_copy_color_4to1);
@@ -48,7 +49,8 @@ mem_planar_dev_spec_op(gx_device *pdev, int dev_spec_op,
{
cmm_dev_profile_t *dev_profile;
- if (dev_spec_op == gxdso_supports_devn) {
+ if (dev_spec_op == gxdso_supports_devn
+ || dev_spec_op == gxdso_skip_icc_component_validation) {
dev_proc(pdev, get_profile)(pdev, &dev_profile);
if (dev_profile != NULL && dev_profile->supports_devn &&
dev_proc(pdev, fill_rectangle_hl_color) == mem_planar_fill_rectangle_hl_color)
@@ -80,6 +82,14 @@ int
gdev_mem_set_planar(gx_device_memory * mdev, int num_planes,
const gx_render_plane_t *planes /*[num_planes]*/)
{
+ return gdev_mem_set_planar_interleaved(mdev, num_planes, planes, 0);
+}
+
+int
+gdev_mem_set_planar_interleaved(gx_device_memory * mdev, int num_planes,
+ const gx_render_plane_t *planes /*[num_planes]*/,
+ int interleaved)
+{
int total_depth;
int same_depth = planes[0].depth;
gx_color_index covered = 0;
@@ -114,7 +124,10 @@ gdev_mem_set_planar(gx_device_memory * mdev, int num_planes,
memcpy(mdev->planes, planes, num_planes * sizeof(planes[0]));
mdev->plane_depth = same_depth;
/* Change the drawing procedures. */
- set_dev_proc(mdev, open_device, mem_planar_open);
+ if (interleaved)
+ set_dev_proc(mdev, open_device, mem_planar_open_interleaved);
+ else
+ set_dev_proc(mdev, open_device, mem_planar_open);
/* Regardless of how many planes we are using, always let the
* device know how to handle hl_color. Even if we spot that we
* can get away with a normal device, our callers may want to
@@ -182,6 +195,17 @@ mem_planar_open(gx_device * dev)
return gdev_mem_open_scan_lines(mdev, dev->height);
}
+static int
+mem_planar_open_interleaved(gx_device * dev)
+{
+ gx_device_memory *const mdev = (gx_device_memory *)dev;
+
+ /* Check that we aren't trying to open a chunky device as planar. */
+ if (!dev->is_planar)
+ return_error(gs_error_rangecheck);
+ return gdev_mem_open_scan_lines_interleaved(mdev, dev->height, 1);
+}
+
/*
* We execute drawing operations by patching a few parameters in the
* device structure and then calling the procedure appropriate to the
@@ -2110,6 +2134,7 @@ mem_planar_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
/* First off, see if we can satisfy get_bits_rectangle with just returning
* pointers to the existing data. */
+ if (params->options & GB_RETURN_POINTER)
{
gs_get_bits_params_t copy_params;
byte **base = &scan_line_base(mdev, y);
@@ -2165,6 +2190,57 @@ mem_planar_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
}
}
}
+
+ if ((params->options & GB_RETURN_POINTER) == 0) {
+ /* Can we do the fetch using a faked GB_RETURN_POINTER request
+ * and then copy the data? */
+ gs_get_bits_params_t params2 = *params;
+ gs_get_bits_params_t copy_params;
+ byte **base = &scan_line_base(mdev, y);
+ int code;
+
+ params2.options &= ~GB_RETURN_COPY;
+ params2.options |= GB_RETURN_POINTER;
+
+ copy_params.options =
+ GB_COLORS_NATIVE | GB_PACKING_PLANAR | GB_ALPHA_NONE |
+ (mdev->raster ==
+ bitmap_raster(mdev->width * mdev->color_info.depth) ?
+ GB_RASTER_STANDARD : GB_RASTER_SPECIFIED);
+ params2.raster = mdev->raster;
+ copy_params.raster = mdev->raster;
+ code = gx_get_bits_return_pointer(dev, x, h, &params2,
+ &copy_params, base);
+ if (code >= 0) {
+ /* get_bits worked. Let's copy the data out. */
+ int bpc = mdev->color_info.depth / mdev->color_info.num_components;
+ int left = x;
+ int right = x+w;
+ int i, j;
+ switch (bpc) {
+ case 1: left >>= 3; right = (right+7)>>3; break;
+ case 2: left >>= 2; right = (right+3)>>2; break;
+ case 4: left >>= 1; right = (right+1)>>1; break;
+ case 8: break;
+ case 12: left = (left&~1); left += left>>1;
+ right = right+(right>>1)+(right&1); break;
+ case 16: left *= 2; right *= 2; break;
+ default: return_error(gs_error_rangecheck);
+ }
+ right -= left;
+ for (i = 0; i < mdev->color_info.num_components; i++) {
+ byte *d = params->data[i];
+ const byte *s = params2.data[i];
+ for (j = 0; j < h; j++) {
+ memcpy(d, s, right);
+ d += params->raster;
+ s += params2.raster;
+ }
+ }
+ return code;
+ }
+ }
+
/*
* We can't return the requested plane by itself. Fall back to
* chunky format. This is somewhat painful.