summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2018-09-30 22:57:33 +0100
committerKen Sharp <ken.sharp@artifex.com>2018-10-02 12:28:12 +0100
commitcbdc54055b7db024951daf3dcb3cafe0af458e47 (patch)
treeca35d56a3537cbf846d4664a0dc54b9f2f3a58a6
parent9565f4ca4aab712f411420fa4c8cae79a2cf88ed (diff)
downloadghostpdl-cbdc54055b7db024951daf3dcb3cafe0af458e47.tar.gz
Change device put_image method to match the other methods in the API
The put_image device method was unique in that the device parameter passed to the method was not a pointer to a device structure of the device implementing the method, but was a pointer to a device structure describing a memory device. This allowed the memory device to use code from the underlying device, which knows how its page buffer is laid out, but data from the memory device which rendered the composited transparent operations. However, this doesn't work at all if we have a chain of devices because the device method which we pull from the device at the head of the chain, is not the method used to actually rendeer to the page buffer of the terminating deevice in the chain. This commit alters the prorotype to take two device pointers, one for the 'terget' device, and one for the memory device which executed the put_image. This allows the final device in the chain to use its own code to format the buffer pointers from the memory device, while allowing intermediate devices to simply pass on the call. Note that previously a few places checked the put_image method against gx_default_put_image (before the device API rationalisation this was a check against NULL) and only called put_image if it was not the default. Now that we have a default implementation (which returns an error), and knowing that the existing device methods return an error if they do not implment some aspect of the memory layout, we can avoid the test altogether; simply call the put_image, the code is already prepared to deal with an error return whether that be because the device does not implement the method or becuase the device cannot cope with some aspect of the layout.
-rw-r--r--base/gdevdflt.c2
-rw-r--r--base/gdevepo.c4
-rw-r--r--base/gdevflp.c4
-rw-r--r--base/gdevmem.c20
-rw-r--r--base/gdevmpla.c4
-rw-r--r--base/gdevnfwd.c17
-rw-r--r--base/gdevoflt.c4
-rw-r--r--base/gdevp14.c11
-rw-r--r--base/gdevsclass.c4
-rw-r--r--base/gxblend1.c11
-rw-r--r--base/gxdevcli.h2
-rw-r--r--base/gxdevice.h1
-rw-r--r--devices/gdevbit.c4
-rw-r--r--devices/gdevpng.c4
14 files changed, 44 insertions, 48 deletions
diff --git a/base/gdevdflt.c b/base/gdevdflt.c
index b5bd82b0a..3e00bffe0 100644
--- a/base/gdevdflt.c
+++ b/base/gdevdflt.c
@@ -1171,7 +1171,7 @@ gx_default_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
}
int
-gx_default_put_image(gx_device *dev, const byte **buffers, int num_chan, int x, int y, int width, int height, int row_stride, int alpha_plane_index, int tag_plane_index)
+gx_default_put_image(gx_device *dev, gx_device *mdev, const byte **buffers, int num_chan, int x, int y, int width, int height, int row_stride, int alpha_plane_index, int tag_plane_index)
{
return_error(gs_error_undefined);
}
diff --git a/base/gdevepo.c b/base/gdevepo.c
index 77ab4f698..944bd0632 100644
--- a/base/gdevepo.c
+++ b/base/gdevepo.c
@@ -466,7 +466,7 @@ int epo_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa,
return dev_proc(dev, fill_linear_color_triangle)(dev, fa, p0, p1, p2, c0, c1, c2);
}
-int epo_put_image(gx_device *dev, const byte **buffers, int num_chan, int x, int y,
+int epo_put_image(gx_device *dev, gx_device *mdev, const byte **buffers, int num_chan, int x, int y,
int width, int height, int row_stride,
int alpha_plane_index, int tag_plane_index)
{
@@ -474,7 +474,7 @@ int epo_put_image(gx_device *dev, const byte **buffers, int num_chan, int x, int
if (code != 0)
return code;
- return dev_proc(dev, put_image)(dev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index);
+ return dev_proc(dev, put_image)(dev, mdev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index);
}
int epo_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte,
diff --git a/base/gdevflp.c b/base/gdevflp.c
index 3e4e6abdb..fa42e11de 100644
--- a/base/gdevflp.c
+++ b/base/gdevflp.c
@@ -1132,7 +1132,7 @@ int flp_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
return 0;
}
-int flp_put_image(gx_device *dev, const byte **buffers, int num_chan, int x, int y,
+int flp_put_image(gx_device *dev, gx_device *mdev, const byte **buffers, int num_chan, int x, int y,
int width, int height, int row_stride,
int alpha_plane_index, int tag_plane_index)
{
@@ -1141,7 +1141,7 @@ int flp_put_image(gx_device *dev, const byte **buffers, int num_chan, int x, int
if (code < 0)
return code;
if (!code)
- return default_subclass_put_image(dev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index);
+ return default_subclass_put_image(dev, mdev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index);
return 0;
}
diff --git a/base/gdevmem.c b/base/gdevmem.c
index 046db38da..8a1d3d0e7 100644
--- a/base/gdevmem.c
+++ b/base/gdevmem.c
@@ -180,25 +180,7 @@ gs_make_mem_device(gx_device_memory * dev, const gx_device_memory * mdproto,
dev->cached_colors = target->cached_colors;
dev->graphics_type_tag = target->graphics_type_tag; /* initialize to same as target */
- /* Do a copy of put_image since it needs the source buffer */
-
- /* This is truly ugly. The PDF14 device expects to check for a device implementing a put_image
- * method, which is quite reasonable, but, those devices which do implement a put_image
- * method expect to be called not with their own device, but with the memory device!
- * This means that if we have any device in the way (subclassing, forwarding, whatever)
- * then this will fail, horribly. The only way to get this to work is to go right to
- * the end of the chain of devices, copy the method from the real terminating device, and
- * then call that directly. Thus completely bypassing the chain.
- * This is awful. We should revise this so that we pass the 'memroy device' as an additional
- * parameter, rather than overriding the actual device, so that we can pass this along the
- * chain. We'd also need to alter the code which checks the put_image method against gx_default_put_image
- * and have that walk the chain of devices, or implement a spec_op to query whether the device impleemnts
- * put_image.
- */
- while (target->child)
- target = target->child;
-
- set_dev_proc(dev, put_image, target->procs.put_image);
+ set_dev_proc(dev, put_image, gx_forward_put_image);
set_dev_proc(dev, dev_spec_op, gx_default_dev_spec_op);
}
if (dev->color_info.depth == 1) {
diff --git a/base/gdevmpla.c b/base/gdevmpla.c
index 9b159714b..120b3a64d 100644
--- a/base/gdevmpla.c
+++ b/base/gdevmpla.c
@@ -254,11 +254,11 @@ put_image_copy_planes(gx_device * dev, const byte **base_ptr, int sourcex,
/* Put image command for copying the planar image buffers with or without
alpha directly to the device buffer */
static int
-mem_planar_put_image(gx_device *pdev, const byte **buffers, int num_chan, int xstart,
+mem_planar_put_image(gx_device *pdev, gx_device *pmdev, const byte **buffers, int num_chan, int xstart,
int ystart, int width, int height, int row_stride,
int alpha_plane_index, int tag_plane_index)
{
- gx_device_memory * const mdev = (gx_device_memory *)pdev;
+ gx_device_memory * const mdev = (gx_device_memory *)pmdev;
/* We don't want alpha, return 0 to ask for the pdf14 device to do the
alpha composition. We also do not want chunky data coming in or to deal
diff --git a/base/gdevnfwd.c b/base/gdevnfwd.c
index 980170ec8..9c9440c71 100644
--- a/base/gdevnfwd.c
+++ b/base/gdevnfwd.c
@@ -112,6 +112,7 @@ gx_device_forward_fill_in_procs(register gx_device_forward * dev)
fill_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
fill_dev_proc(dev, ret_devn_params, gx_forward_ret_devn_params);
fill_dev_proc(dev, fillpage, gx_forward_fillpage);
+ fill_dev_proc(dev, put_image, gx_forward_put_image);
fill_dev_proc(dev, get_profile, gx_forward_get_profile);
fill_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
fill_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2);
@@ -1013,7 +1014,21 @@ gx_forward_set_graphics_type_tag(gx_device *dev, gs_graphics_type_tag_t graphics
dev->graphics_type_tag = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) | graphics_type_tag;
}
-/* ---------------- The null device(s) ---------------- */
+int
+gx_forward_put_image(gx_device *pdev, gx_device *mdev, const byte **buffers, int num_chan, int xstart,
+ int ystart, int width, int height, int row_stride,
+ int alpha_plane_index, int tag_plane_index)
+{
+ gx_device_forward * const fdev = (gx_device_forward *)pdev;
+ gx_device *tdev = fdev->target;
+
+ if (tdev != 0)
+ return dev_proc(tdev, put_image)(tdev, mdev, buffers, num_chan, xstart, ystart, width, height, row_stride, alpha_plane_index, tag_plane_index);
+ else
+ return gx_default_put_image(tdev, mdev, buffers, num_chan, xstart, ystart, width, height, row_stride, alpha_plane_index, tag_plane_index);
+}
+
+/* ---------------- The null device(s) ---------_plane_index------- */
static dev_proc_get_initial_matrix(gx_forward_upright_get_initial_matrix);
static dev_proc_fill_rectangle(null_fill_rectangle);
diff --git a/base/gdevoflt.c b/base/gdevoflt.c
index 966012d48..cb50465d4 100644
--- a/base/gdevoflt.c
+++ b/base/gdevoflt.c
@@ -530,12 +530,12 @@ int obj_filter_fill_linear_color_triangle(gx_device *dev, const gs_fill_attribut
return 0;
}
-int obj_filter_put_image(gx_device *dev, const byte **buffers, int num_chan, int x, int y,
+int obj_filter_put_image(gx_device *dev, gx_device *mdev, const byte **buffers, int num_chan, int x, int y,
int width, int height, int row_stride,
int alpha_plane_index, int tag_plane_index)
{
if ((dev->ObjectFilter & FILTERIMAGE) == 0)
- return default_subclass_put_image(dev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index);
+ return default_subclass_put_image(dev, mdev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index);
return 0;
}
diff --git a/base/gdevp14.c b/base/gdevp14.c
index f89bc04db..3019131c7 100644
--- a/base/gdevp14.c
+++ b/base/gdevp14.c
@@ -1883,11 +1883,10 @@ pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
if (dev_target_profile == NULL)
return gs_throw_code(gs_error_Fatal);
- /* See if the target device has a put_image command. If yes then see if it
- can handle the image data directly. If it cannot, then we will need to
+ /* See if the target device can handle the image data directly. If it cannot, then we will need to
use the begin_typed_image interface, which cannot pass along tag nor
alpha data to the target device. */
- if (dev_proc(target, put_image) != gx_default_put_image) {
+ {
pdf14_buf *cm_result = NULL;
int alpha_offset, tag_offset;
const byte *buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
@@ -1946,7 +1945,7 @@ pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
/* See if the target device can handle the data with alpha component */
for (i = 0; i < buf->n_planes; i++)
buf_ptrs[i] = buf_ptr + i * buf->planestride;
- code = dev_proc(target, put_image) (target, buf_ptrs, num_comp,
+ code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
rect.p.x, rect.p.y, width, height,
buf->rowstride, alpha_offset,
tag_offset);
@@ -1973,7 +1972,7 @@ pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
/* Try again now with just the tags */
alpha_offset = 0;
- code = dev_proc(target, put_image) (target, buf_ptrs, num_comp,
+ code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
rect.p.x, rect.p.y, width, height,
buf->rowstride, alpha_offset,
tag_offset);
@@ -1982,7 +1981,7 @@ pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
/* We processed some or all of the rows. Continue until we are done */
num_rows_left = height - code;
while (num_rows_left > 0) {
- code = dev_proc(target, put_image) (target, buf_ptrs, num_comp,
+ code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
rect.p.x, rect.p.y + code, width,
num_rows_left, buf->rowstride,
alpha_offset, tag_offset);
diff --git a/base/gdevsclass.c b/base/gdevsclass.c
index 20c7f529e..0f267741f 100644
--- a/base/gdevsclass.c
+++ b/base/gdevsclass.c
@@ -792,12 +792,12 @@ int default_subclass_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
return 0;
}
-int default_subclass_put_image(gx_device *dev, const byte **buffers, int num_chan, int x, int y,
+int default_subclass_put_image(gx_device *dev, gx_device *mdev, const byte **buffers, int num_chan, int x, int y,
int width, int height, int row_stride,
int alpha_plane_index, int tag_plane_index)
{
if (dev->child)
- return dev_proc(dev->child, put_image)(dev->child, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index);
+ return dev_proc(dev->child, put_image)(dev->child, mdev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index);
return 0;
}
diff --git a/base/gxblend1.c b/base/gxblend1.c
index bd58d4b01..183190886 100644
--- a/base/gxblend1.c
+++ b/base/gxblend1.c
@@ -722,9 +722,8 @@ gx_put_blended_image_cmykspot(gx_device *target, byte *buf_ptr, int planestride,
input_map[num_known_comp++] = comp_num + 4;
}
}
- /* See if the target device has a put_image command. If
- yes then see if it can handle the image data directly. */
- if (target->procs.put_image != gx_default_put_image) {
+
+ {
/* See if the target device can handle the data in its current
form with the alpha component */
int alpha_offset = num_comp;
@@ -733,7 +732,7 @@ gx_put_blended_image_cmykspot(gx_device *target, byte *buf_ptr, int planestride,
int i;
for (i = 0; i < num_comp; i++)
buf_ptrs[i] = buf_ptr + i * planestride;
- code = dev_proc(target, put_image) (target, buf_ptrs, num_comp,
+ code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
rect.p.x, rect.p.y, width, height,
rowstride,
num_comp,tag_offset);
@@ -758,7 +757,7 @@ gx_put_blended_image_cmykspot(gx_device *target, byte *buf_ptr, int planestride,
#endif
/* Try again now */
alpha_offset = 0;
- code = dev_proc(target, put_image) (target, buf_ptrs, num_comp,
+ code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
rect.p.x, rect.p.y, width, height,
rowstride,
alpha_offset, tag_offset);
@@ -767,7 +766,7 @@ gx_put_blended_image_cmykspot(gx_device *target, byte *buf_ptr, int planestride,
/* We processed some or all of the rows. Continue until we are done */
num_rows_left = height - code;
while (num_rows_left > 0) {
- code = dev_proc(target, put_image) (target, buf_ptrs, num_comp,
+ code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
rect.p.x, rect.p.y+code, width,
num_rows_left, rowstride,
alpha_offset, tag_offset);
diff --git a/base/gxdevcli.h b/base/gxdevcli.h
index 757694c4d..b35ed4148 100644
--- a/base/gxdevcli.h
+++ b/base/gxdevcli.h
@@ -1514,7 +1514,7 @@ typedef struct gs_devn_params_s gs_devn_params;
dev_t_proc_pop_transparency_state(proc, gx_device)
#define dev_t_proc_put_image(proc, dev_t)\
- int proc(gx_device *dev, const byte **buffers, int num_chan, int x, int y,\
+ int proc(gx_device *dev, gx_device *mdev, const byte **buffers, int num_chan, int x, int y,\
int width, int height, int row_stride,\
int alpha_plane_index, int tag_plane_index)
#define dev_proc_put_image(proc)\
diff --git a/base/gxdevice.h b/base/gxdevice.h
index 4b6c5198c..abf0c534f 100644
--- a/base/gxdevice.h
+++ b/base/gxdevice.h
@@ -408,6 +408,7 @@ dev_proc_fill_linear_color_triangle(gx_forward_fill_linear_color_triangle);
dev_proc_update_spot_equivalent_colors(gx_forward_update_spot_equivalent_colors);
dev_proc_ret_devn_params(gx_forward_ret_devn_params);
dev_proc_fillpage(gx_forward_fillpage);
+dev_proc_put_image(gx_forward_put_image);
dev_proc_copy_planes(gx_forward_copy_planes);
dev_proc_create_compositor(gx_forward_create_compositor);
dev_proc_get_profile(gx_forward_get_profile);
diff --git a/devices/gdevbit.c b/devices/gdevbit.c
index fa7f9f0cd..77a520c73 100644
--- a/devices/gdevbit.c
+++ b/devices/gdevbit.c
@@ -828,11 +828,11 @@ bittags_print_page(gx_device_printer * pdev, FILE * prn_stream)
}
static int
-bit_put_image(gx_device *pdev, const byte **buffers, int num_chan, int xstart,
+bit_put_image(gx_device *pdev, gx_device *mdev, const byte **buffers, int num_chan, int xstart,
int ystart, int width, int height, int row_stride,
int alpha_plane_index, int tag_plane_index)
{
- gx_device_memory *pmemdev = (gx_device_memory *)pdev;
+ gx_device_memory *pmemdev = (gx_device_memory *)mdev;
byte *buffer_prn;
int yend = ystart + height;
int xend = xstart + width;
diff --git a/devices/gdevpng.c b/devices/gdevpng.c
index cf731018d..26fc5a8ab 100644
--- a/devices/gdevpng.c
+++ b/devices/gdevpng.c
@@ -858,11 +858,11 @@ pngalpha_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc)
/* Handle the RGBA planes from the PDF 1.4 compositor */
static int
-pngalpha_put_image (gx_device *pdev, const byte **buffers, int num_chan, int xstart,
+pngalpha_put_image (gx_device *pdev, gx_device *mdev, const byte **buffers, int num_chan, int xstart,
int ystart, int width, int height, int row_stride,
int alpha_plane_index, int tag_plane_index)
{
- gx_device_memory *pmemdev = (gx_device_memory *)pdev;
+ gx_device_memory *pmemdev = (gx_device_memory *)mdev;
byte *buffer_prn;
int yend = ystart + height;
int xend = xstart + width;