diff options
author | Robin Watts <Robin.Watts@artifex.com> | 2021-06-30 11:23:31 +0100 |
---|---|---|
committer | Robin Watts <Robin.Watts@artifex.com> | 2021-07-01 00:27:56 +0100 |
commit | 2f7f448a4b73b8f996fa9196527da1db5cc520e2 (patch) | |
tree | 5e996d8e57f907800de3cf64b0bf07336a6bd09f | |
parent | a8671762033fa55823068fbb208983f7435b70d6 (diff) | |
download | ghostpdl-2f7f448a4b73b8f996fa9196527da1db5cc520e2.tar.gz |
Add gx_blank_get_bits_rectangle.
High level devices do not generally keep a rendered bitmap
version of the page. As such they cannot honour get_bits_rectangle
requests.
This causes certain rendering operations to fail; notably those
that involve ROPs that involve 'D'. This can cause runs to
error out prematurely.
For instance, a 72dpi page mode PCL run of j9_acrobat.pcl to the
lips4v device dies with an error.
Accordingly, we add a gx_blank_get_bits_rectangle routine that
returns 'empty' rectangles, and we make lips4v use that. This
gives imperfect renderings (in the same way that pdfwriting
files that use ROPs gives imperfect renderings), but we do at
least get a rendering out at the end.
In testing this, I found a suspect spot in lips4v where valgrind
spots us operating on uninitialised data. Patch around that to
init it to 0 to quell valgrind.
-rw-r--r-- | base/gdevdgbr.c | 30 | ||||
-rw-r--r-- | base/gxdevice.h | 1 | ||||
-rw-r--r-- | contrib/lips4/gdevl4v.c | 13 |
3 files changed, 44 insertions, 0 deletions
diff --git a/base/gdevdgbr.c b/base/gdevdgbr.c index 058bf9141..c5922e3c1 100644 --- a/base/gdevdgbr.c +++ b/base/gdevdgbr.c @@ -491,3 +491,33 @@ gx_default_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, { return_error(gs_error_unknownerror); } + +int gx_blank_get_bits_rectangle(gx_device *dev, const gs_int_rect *prect, + gs_get_bits_params_t *params, gs_int_rect **unread) +{ + int supported = GB_COLORS_NATIVE | + GB_ALPHA_NONE | + GB_DEPTH_8 | + GB_PACKING_CHUNKY | + GB_RETURN_COPY | + GB_ALIGN_STANDARD | + GB_OFFSET_0 | + GB_RASTER_STANDARD; + unsigned char *ptr = params->data[0]; + int bytes = (prect->q.x - prect->p.x) * dev->color_info.num_components; + int col = dev->color_info.num_components > 3 ? 0 : 0xff; + int raster = bitmap_raster(dev->width * dev->color_info.num_components); + int y; + + if ((params->options & supported) != supported) + return_error(gs_error_unknownerror); + + params->options = supported; + + for (y = prect->p.y; y < prect->q.y; y++) { + memset(ptr, col, bytes); + ptr += raster; + } + + return 0; +} diff --git a/base/gxdevice.h b/base/gxdevice.h index a678c6588..ceff5aa7c 100644 --- a/base/gxdevice.h +++ b/base/gxdevice.h @@ -277,6 +277,7 @@ dev_proc_get_clipping_box(gx_default_get_clipping_box); dev_proc_get_clipping_box(gx_get_largest_clipping_box); dev_proc_begin_typed_image(gx_default_begin_typed_image); dev_proc_get_bits_rectangle(gx_default_get_bits_rectangle); /* just returns error */ +dev_proc_get_bits_rectangle(gx_blank_get_bits_rectangle); dev_proc_composite(gx_no_composite); /* default is for ordinary "leaf" devices, null is for */ /* devices that only care about coverage and not contents. */ diff --git a/contrib/lips4/gdevl4v.c b/contrib/lips4/gdevl4v.c index 5cba57119..1cdc17c41 100644 --- a/contrib/lips4/gdevl4v.c +++ b/contrib/lips4/gdevl4v.c @@ -179,6 +179,7 @@ lips4v_initialize_device_procs(gx_device *dev) set_dev_proc(dev, fill_parallelogram, gdev_vector_fill_parallelogram); set_dev_proc(dev, fill_triangle, gdev_vector_fill_triangle); set_dev_proc(dev, begin_typed_image, lips4v_begin_typed_image); + set_dev_proc(dev, get_bits_rectangle, gx_blank_get_bits_rectangle); } gx_device_lips4v far_data gs_lips4v_device = { @@ -2090,6 +2091,18 @@ lips4v_fill_mask(gx_device * dev, byte *buf = gs_alloc_bytes(vdev->memory, num_bytes, "lips4v_fill_mask(buf)"); + /* This code seems suspect to me; we allocate a buffer + * rounding each line up to a multiple of 4, and then + * fill it without reference to this rounding. I suspect + * that each line should be padded, rather than all the + * data being crammed at the start, but I can't make that + * change in the absence of any way to test this. I will + * make do by adding the memset here so that any untouched + * bytes are at least consistently set to 0 to avoid + * indeterminisms (and valgrind errors). RJW */ + if (width_bytes * h < num_bytes) { + memset(buf + width_bytes * h, 0, num_bytes - width_bytes * h); + } for (i = 0; i < h; ++i) { memcpy(buf + i * width_bytes, data + (data_x >> 3) + i * raster, width_bytes); |