diff options
author | Robin Watts <robin.watts@artifex.com> | 2011-11-14 12:19:32 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2011-11-14 18:12:20 +0000 |
commit | 96ab69c8bcc1bcf3e366b494ed099dc5b46009fe (patch) | |
tree | 4aa5b3a2f2655f896c7a3aefd1272fc6f5ae7d77 /gs/base/gxclrast.c | |
parent | 940b007282d74686a20aa5cf434d20353680344c (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.c | 212 |
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: |