summaryrefslogtreecommitdiff
path: root/gs/base/gxclrast.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2011-11-14 12:19:32 +0000
committerRobin Watts <robin.watts@artifex.com>2011-11-14 18:12:20 +0000
commit96ab69c8bcc1bcf3e366b494ed099dc5b46009fe (patch)
tree4aa5b3a2f2655f896c7a3aefd1272fc6f5ae7d77 /gs/base/gxclrast.c
parent940b007282d74686a20aa5cf434d20353680344c (diff)
Planar rop fixes; extensive changes throughout code.
The changes here are largely forced upon us by the rop source device, the internal mechanism used within the gs lib to cope with performing rop operations with drawing operations. The rop source device is created and is given a 'source'. Any operations then done to that device are then passed on to its target device rewritten into a form that will cause the output to be ropped with the source. This causes problems when the source is in planar format (such as when the source is a pattern tile intended for use on a planar device). There is no way to call strip_copy_rop with planar data currently, neither can it easily be shoehorned through. We therefore add a new 'strip_copy_rop2' entrypoint that takes an additional 'planar_height' parameter that gives the number of lines of data before the next planes data starts. We add implementations of this call throughout the code; some are very simple (bbox, null, trace, clip, clip2, clip2, tile_clip etc). Others 'common up' with the strip_copy_rop (gx_default, mem_planar). The underlying memory devices should never be called with strip_copy_rop2 as the planar data will always be rewritten to chunky format before this happens. We are free to change this approach later if we want. The gx_rop_source_t structure used by the rop source device is extended to have a new planar_height field, and the rop source device itself extended to pass this on. Various places that create this structure now initialise that correctly. The clist reader/writer is updated to send the extra planar_height field through and call strip_cop_rop or strip_copy_rop2 as appropriate. In a similar vein, we are forced to change the copy_plane entry point to be copy_planes (as it is impossible (or very hard at least) for the rop source device to implement copy_plane). This incorporates changes from Michael to the new "fast threshold" image halftoning code to make it use the new copy_planes operation.
Diffstat (limited to 'gs/base/gxclrast.c')
-rw-r--r--gs/base/gxclrast.c212
1 files changed, 124 insertions, 88 deletions
diff --git a/gs/base/gxclrast.c b/gs/base/gxclrast.c
index 467fa09b5..059517ffd 100644
--- a/gs/base/gxclrast.c
+++ b/gs/base/gxclrast.c
@@ -533,7 +533,7 @@ clist_playback_band(clist_playback_action playback_action,
bool clipper_dev_open;
patch_fill_state_t pfs;
int op = 0;
- short plane = 0;
+ int plane_height = 0;
#ifdef DEBUG
stream_state *st = s->state; /* Save because s_close resets s->state. */
@@ -925,9 +925,15 @@ in: /* Initialize for a new page. */
}
state.rect.width += (op & 7) + cmd_min_dw_tiny;
break;
- case cmd_op_copy_mono_plane >> 4:
- cmd_getw(plane, cbp);
- depth = 1;
+ case cmd_op_copy_mono_planes >> 4:
+ cmd_getw(plane_height, cbp);
+ if (plane_height == 0) {
+ /* We are doing a copy mono */
+ depth = 1;
+ } else {
+ depth = tdev->color_info.depth;
+ }
+ if_debug1('L', " plane_height=0x%x", plane_height);
goto copy;
case cmd_op_copy_color_alpha >> 4:
if (state.color_is_alpha) {
@@ -935,6 +941,7 @@ in: /* Initialize for a new page. */
depth = *cbp++;
} else
depth = tdev->color_info.depth;
+ plane_height = 0;
copy:cmd_getw(state.rect.x, cbp);
cmd_getw(state.rect.y, cbp);
if (op & 8) { /* Use the current "tile". */
@@ -956,20 +963,27 @@ in: /* Initialize for a new page. */
/* depth was set already. */
uint width_bits, width_bytes;
uint bytes;
+ uint planes = 1;
+ uint plane_depth = depth;
+ uint pln;
+ byte compression = op & 3;
cmd_getw(state.rect.width, cbp);
cmd_getw(state.rect.height, cbp);
- width_bits = state.rect.width * depth;
- bytes =
- clist_bitmap_bytes(width_bits,
- state.rect.height,
- op & 3, &width_bytes,
- (uint *)&raster);
+ if (plane_height != 0) {
+ planes = tdev->color_info.num_components;
+ plane_depth /= planes;
+ }
+ width_bits = state.rect.width * plane_depth;
+ bytes = clist_bitmap_bytes(width_bits,
+ state.rect.height,
+ op & 3, &width_bytes,
+ (uint *)&raster);
/* copy_mono and copy_color/alpha */
/* ensure that the bits will fit in a single buffer, */
/* even after decompression if compressed. */
#ifdef DEBUG
- if (bytes > cbuf_size) {
+ if (planes * bytes > cbuf_size) {
lprintf6("bitmap size exceeds buffer! width=%d raster=%d height=%d\n file pos %ld buf pos %d/%d\n",
state.rect.width, raster,
state.rect.height,
@@ -979,72 +993,80 @@ in: /* Initialize for a new page. */
goto out;
}
#endif
- if (op & 3) { /* Decompress the image data. */
- stream_cursor_read r;
- stream_cursor_write w;
-
- /* We don't know the data length a priori, */
- /* so to be conservative, we read */
- /* the uncompressed size. */
- uint cleft = cbuf.end - cbp;
-
- if (cleft < bytes && !cbuf.end_status) {
- uint nread = cbuf_size - cleft;
+ for (pln = 0; pln < planes; pln++)
+ {
+ byte *plane_bits = data_bits + plane_height * raster;
+ if (pln)
+ compression = *cbp++;
+ if (compression) { /* Decompress the image data. */
+ stream_cursor_read r;
+ stream_cursor_write w;
+
+ /* We don't know the data length a priori, */
+ /* so to be conservative, we read */
+ /* the uncompressed size. */
+ uint cleft = cbuf.end - cbp;
-# ifdef DEBUG
- code = top_up_offset_map(st, cbuf.data, cbp, cbuf.end);
- if (code < 0)
- return code;
-# endif
- memmove(cbuf.data, cbp, cleft);
- cbuf.end_status = sgets(s, cbuf.data + cleft, nread, &nread);
- set_cb_end(&cbuf, cbuf.data + cleft + nread);
- cbp = cbuf.data;
- }
- r.ptr = cbp - 1;
- r.limit = cbuf.end - 1;
- w.ptr = data_bits - 1;
- w.limit = w.ptr + data_bits_size;
- switch (op & 3) {
- case cmd_compress_rle:
- {
- stream_RLD_state sstate;
+ if (cleft < bytes && !cbuf.end_status) {
+ uint nread = cbuf_size - cleft;
- clist_rld_init(&sstate);
- /* The process procedure can't fail. */
- (*s_RLD_template.process)
- ((stream_state *)&sstate, &r, &w, true);
- }
- break;
- case cmd_compress_cfe:
- {
- stream_CFD_state sstate;
-
- clist_cfd_init(&sstate,
- width_bytes << 3 /*state.rect.width */ ,
- state.rect.height, mem);
- /* The process procedure can't fail. */
- (*s_CFD_template.process)
- ((stream_state *)&sstate, &r, &w, true);
- (*s_CFD_template.release)
- ((stream_state *)&sstate);
- }
- break;
- default:
- goto bad_op;
+# ifdef DEBUG
+ code = top_up_offset_map(st, cbuf.data, cbp, cbuf.end);
+ if (code < 0)
+ return code;
+# endif
+ memmove(cbuf.data, cbp, cleft);
+ cbuf.end_status = sgets(s, cbuf.data + cleft, nread, &nread);
+ set_cb_end(&cbuf, cbuf.data + cleft + nread);
+ cbp = cbuf.data;
+ }
+ r.ptr = cbp - 1;
+ r.limit = cbuf.end - 1;
+ w.ptr = plane_bits - 1;
+ w.limit = w.ptr + data_bits_size;
+ switch (compression) {
+ case cmd_compress_rle:
+ {
+ stream_RLD_state sstate;
+
+ clist_rld_init(&sstate);
+ /* The process procedure can't fail. */
+ (*s_RLD_template.process)
+ ((stream_state *)&sstate, &r, &w, true);
+ }
+ break;
+ case cmd_compress_cfe:
+ {
+ stream_CFD_state sstate;
+
+ clist_cfd_init(&sstate,
+ width_bytes << 3 /*state.rect.width */ ,
+ state.rect.height, mem);
+ /* The process procedure can't fail. */
+ (*s_CFD_template.process)
+ ((stream_state *)&sstate, &r, &w, true);
+ (*s_CFD_template.release)
+ ((stream_state *)&sstate);
+ }
+ break;
+ default:
+ goto bad_op;
+ }
+ cbp = r.ptr + 1;
+ if (pln == 0)
+ source = data_bits;
+ } else if ((state.rect.height > 1 && width_bytes != raster) ||
+ (plane_height != 0)) {
+ if (pln == 0)
+ source = data_bits;
+ cbp = cmd_read_short_bits(&cbuf, plane_bits, width_bytes,
+ state.rect.height,
+ raster, cbp);
+ } else {
+ /* Never used for planar data */
+ cmd_read(cbuf.data, bytes, cbp);
+ source = cbuf.data;
}
- cbp = r.ptr + 1;
- source = data_bits;
- } else if (state.rect.height > 1 &&
- width_bytes != raster
- ) {
- source = data_bits;
- cbp = cmd_read_short_bits(&cbuf, source, width_bytes,
- state.rect.height,
- raster, cbp);
- } else {
- cmd_read(cbuf.data, bytes, cbp);
- source = cbuf.data;
}
#ifdef DEBUG
if (gs_debug_c('L')) {
@@ -2015,15 +2037,29 @@ idata: data_size = 0;
colors[0] = colors[1] = state.colors[1];
log_op = state.lop;
pcolor = colors;
- do_rop:code = (*dev_proc(tdev, strip_copy_rop))
- (tdev, source, data_x, raster, gx_no_bitmap_id,
- pcolor, &state_tile,
- (state.tile_colors[0] == gx_no_color_index &&
- state.tile_colors[1] == gx_no_color_index ?
- NULL : state.tile_colors),
- state.rect.x - x0, state.rect.y - y0,
- state.rect.width - data_x, state.rect.height,
- tile_phase.x, tile_phase.y, log_op);
+ do_rop:if (plane_height == 0) {
+ code = (*dev_proc(tdev, strip_copy_rop))
+ (tdev, source, data_x, raster, gx_no_bitmap_id,
+ pcolor, &state_tile,
+ (state.tile_colors[0] == gx_no_color_index &&
+ state.tile_colors[1] == gx_no_color_index ?
+ NULL : state.tile_colors),
+ state.rect.x - x0, state.rect.y - y0,
+ state.rect.width - data_x, state.rect.height,
+ tile_phase.x, tile_phase.y, log_op);
+ } else {
+ code = (*dev_proc(tdev, strip_copy_rop2))
+ (tdev, source, data_x, raster, gx_no_bitmap_id,
+ pcolor, &state_tile,
+ (state.tile_colors[0] == gx_no_color_index &&
+ state.tile_colors[1] == gx_no_color_index ?
+ NULL : state.tile_colors),
+ state.rect.x - x0, state.rect.y - y0,
+ state.rect.width - data_x, state.rect.height,
+ tile_phase.x, tile_phase.y, log_op,
+ plane_height);
+ plane_height = 0;
+ }
data_x = 0;
break;
case cmd_op_tile_rect >> 4:
@@ -2042,7 +2078,7 @@ idata: data_size = 0;
state.tile_colors[0], state.tile_colors[1],
tile_phase.x, tile_phase.y);
break;
- case cmd_op_copy_mono_plane >> 4:
+ case cmd_op_copy_mono_planes >> 4:
if (state.lop_enabled) {
pcolor = state.colors;
log_op = state.lop;
@@ -2058,21 +2094,21 @@ idata: data_size = 0;
state.rect.width - data_x, state.rect.height,
&dev_color, 1, imager_state.log_op, pcpath);
} else {
- if (plane == 255) {
+ if (plane_height == 0) {
code = (*dev_proc(tdev, copy_mono))
(tdev, source, data_x, raster, gx_no_bitmap_id,
state.rect.x - x0, state.rect.y - y0,
state.rect.width - data_x, state.rect.height,
state.colors[0], state.colors[1]);
} else {
- code = (*dev_proc(tdev, copy_plane))
+ code = (*dev_proc(tdev, copy_planes))
(tdev, source, data_x, raster, gx_no_bitmap_id,
state.rect.x - x0, state.rect.y - y0,
state.rect.width - data_x, state.rect.height,
- plane);
+ plane_height);
}
}
- plane = -1;
+ plane_height = 0;
data_x = 0;
break;
case cmd_op_copy_color_alpha >> 4: