summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2022-03-08 09:45:27 +0000
committerRobin Watts <Robin.Watts@artifex.com>2022-03-08 11:16:18 +0000
commit167a3c05ffa5fa4f8785cc104e7eb7a4b9b4c781 (patch)
tree6b94745aef0e486cdd30a0c2ad99e36cfbbea24c
parentb1d42fd198430ce82a7bffe182f672802b6d98ec (diff)
downloadghostpdl-167a3c05ffa5fa4f8785cc104e7eb7a4b9b4c781.tar.gz
Bug 705013: Fix SEGV in planc device with clist.
The use of set_bits for planar data goes wrong, as on reading we set num_planes to 1. Introduce a new set_bits_planar operation that includes num_planes and use that as appropriate.
-rw-r--r--base/gxclbits.c13
-rw-r--r--base/gxcldev.h6
-rw-r--r--base/gxclrast.c12
3 files changed, 22 insertions, 9 deletions
diff --git a/base/gxclbits.c b/base/gxclbits.c
index 7f08db98b..6ccc65a75 100644
--- a/base/gxclbits.c
+++ b/base/gxclbits.c
@@ -788,7 +788,9 @@ clist_change_bits(gx_device_clist_writer * cldev, gx_clist_state * pcls,
/* the reading phase, not the writing phase. */
ulong offset = (byte *) loc.tile - cldev->cache_chunk->data;
uint rsize = 2 + cmd_size_w(loc.tile->width) +
- cmd_size_w(loc.tile->height) + cmd_size_w(loc.index) +
+ cmd_size_w(loc.tile->height) +
+ (loc.tile->num_planes > 1 ? 1 : 0) +
+ cmd_size_w(loc.index) +
cmd_size_w(offset);
byte *dp;
uint csize;
@@ -812,15 +814,18 @@ clist_change_bits(gx_device_clist_writer * cldev, gx_clist_state * pcls,
return code;
if_debug1m('L', cldev->memory,
"[L] fake end_run: really set_bits[%d]\n", csize);
- *dp = cmd_count_op(cmd_opv_set_bits, csize, cldev->memory);
+ *dp = cmd_count_op(loc.tile->num_planes > 1 ? cmd_opv_set_bits_planar : cmd_opv_set_bits,
+ csize, cldev->memory);
dp[1] = (depth << 2) + code;
dp += 2;
dp = cmd_put_w(loc.tile->width, dp);
dp = cmd_put_w(loc.tile->height, dp);
+ if (loc.tile->num_planes > 1)
+ *dp++ = loc.tile->num_planes;
dp = cmd_put_w(loc.index, dp);
cmd_put_w(offset, dp);
- if_debug6m('L', cldev->memory, " compress=%d depth=%d size=(%d,%d) index=%d offset=%d\n",
- code, depth, loc.tile->width, loc.tile->height, loc.index, offset);
+ if_debug7m('L', cldev->memory, " compress=%d depth=%d size=(%d,%d) planes=%d index=%d offset=%d\n",
+ code, depth, loc.tile->width, loc.tile->height, loc.tile->num_planes, loc.index, offset);
if (bit_pcls == NULL) {
memset(ts_mask(loc.tile), 0xff,
cldev->tile_band_mask_size);
diff --git a/base/gxcldev.h b/base/gxcldev.h
index 2fe70ad44..91cfa2cd4 100644
--- a/base/gxcldev.h
+++ b/base/gxcldev.h
@@ -119,6 +119,8 @@ typedef enum {
cmd_op_delta_tile_index = 0xb0, /* +delta+8 */
cmd_op_set_tile_index = 0xc0, /* +index[11:8], index[7:0] */
cmd_op_misc2 = 0xd0, /* (see below) */
+ cmd_opv_set_bits_planar = 0xd0, /* depth*4+compress, width#, height#, */
+ /* num_planes, index#, offset#, <bits> */
cmd_op_fill_rect_hl = 0xd1, /* rect fill with devn color */
cmd_opv_set_fill_adjust = 0xd2, /* adjust_x/y(fixed) */
cmd_opv_set_ctm = 0xd3, /* [per sput/sget_matrix] */
@@ -160,7 +162,7 @@ typedef enum {
#define cmd_misc2_op_name_strings\
- "?d0?", "fill_hl_color", \
+ "set_bits_planar", "fill_hl_color", \
"set_fill_adjust", "set_ctm",\
"set_color_space", "set_misc2", "set_dash", "enable_clip",\
"disable_clip", "begin_clip", "end_clip", "begin_image_rect",\
@@ -223,7 +225,7 @@ typedef enum {
"?f8?", "polyfill", "?fa?", "?fb?",\
"fill_trapezoid", "?fd?", "?fe?", "?ff?"
-/* unused cmd_op values: 0xd0, 0xf2, 0xf7, 0xf8, 0xfa, 0xfb, 0xfd, 0xfe, 0xff */
+/* unused cmd_op values: 0xf2, 0xf7, 0xf8, 0xfa, 0xfb, 0xfd, 0xfe, 0xff */
} gx_cmd_op;
#define cmd_op_name_strings\
diff --git a/base/gxclrast.c b/base/gxclrast.c
index 245cd3ae9..5d042f9ba 100644
--- a/base/gxclrast.c
+++ b/base/gxclrast.c
@@ -785,18 +785,22 @@ in: /* Initialize for a new page. */
goto out;
goto stp;
case cmd_opv_set_bits:
+do_opv_set_bits:
compress = *cbp & 3;
bits.head.depth = *cbp++ >> 2;
cmd_getw(bits.width, cbp);
cmd_getw(bits.height, cbp);
- if_debug4m('L', mem, " compress=%d depth=%d size=(%d,%d)",
+ if (op == cmd_opv_set_bits_planar)
+ cmd_getw(bits.num_planes, cbp);
+ else
+ bits.num_planes = 1;
+ if_debug5m('L', mem, " compress=%d depth=%d size=(%d,%d) planes=%d",
compress, bits.head.depth,
- bits.width, bits.height);
+ bits.width, bits.height, bits.num_planes);
bits.raster =
bitmap_raster(bits.width * bits.head.depth);
bits.x_reps = bits.y_reps = 1;
bits.shift = bits.rep_shift = 0;
- bits.num_planes = 1;
goto stb;
case cmd_opv_set_tile_color:
set_colors = state.tile_colors;
@@ -1267,6 +1271,8 @@ set_phase: /*
continue;
case cmd_op_misc2 >> 4:
switch (op) {
+ case cmd_opv_set_bits_planar:
+ goto do_opv_set_bits;
case cmd_opv_set_fill_adjust:
cmd_get_value(gs_gstate.fill_adjust.x, cbp);
cmd_get_value(gs_gstate.fill_adjust.y, cbp);