[gs-commits] rev 12295 - trunk/gs/base
robin at ghostscript.com
robin at ghostscript.com
Tue Mar 15 17:59:17 UTC 2011
Author: robin
Date: 2011-03-15 17:59:17 +0000 (Tue, 15 Mar 2011)
New Revision: 12295
Modified:
trunk/gs/base/gdevmpla.c
Log:
Add special case mem_planar_copy_color_4to1 code for copying bits
from 4 1 bit planes into 1 4 bit chunky plane.
This helps with performance of the plibk device.
No cluster differences expected.
Modified: trunk/gs/base/gdevmpla.c
===================================================================
--- trunk/gs/base/gdevmpla.c 2011-03-15 16:57:19 UTC (rev 12294)
+++ trunk/gs/base/gdevmpla.c 2011-03-15 17:59:17 UTC (rev 12295)
@@ -26,6 +26,7 @@
static dev_proc_open_device(mem_planar_open);
declare_mem_procs(mem_planar_copy_mono, mem_planar_copy_color, mem_planar_fill_rectangle);
static dev_proc_copy_color(mem_planar_copy_color_24to8);
+static dev_proc_copy_color(mem_planar_copy_color_4to1);
static dev_proc_strip_tile_rectangle(mem_planar_strip_tile_rectangle);
static dev_proc_get_bits_rectangle(mem_planar_get_bits_rectangle);
@@ -91,6 +92,13 @@
(mdev->planes[1].depth == 8) && (mdev->planes[1].shift == 8) &&
(mdev->planes[2].depth == 8) && (mdev->planes[2].shift == 0))
set_dev_proc(mdev, copy_color, mem_planar_copy_color_24to8);
+ else if ((mdev->color_info.depth == 4) &&
+ (mdev->num_planes == 4) &&
+ (mdev->planes[0].depth == 1) && (mdev->planes[0].shift == 3) &&
+ (mdev->planes[1].depth == 1) && (mdev->planes[1].shift == 2) &&
+ (mdev->planes[2].depth == 1) && (mdev->planes[2].shift == 1) &&
+ (mdev->planes[3].depth == 1) && (mdev->planes[3].shift == 0))
+ set_dev_proc(mdev, copy_color, mem_planar_copy_color_4to1);
else
set_dev_proc(mdev, copy_color, mem_planar_copy_color);
set_dev_proc(mdev, copy_alpha, gx_default_copy_alpha);
@@ -273,6 +281,181 @@
return 0;
}
+/* Copy color: Special case the 4 -> 1+1+1+1 case. */
+static int
+mem_planar_copy_color_4to1(gx_device * dev, const byte * base, int sourcex,
+ int sraster, gx_bitmap_id id,
+ int x, int y, int w, int h)
+{
+ gx_device_memory * const mdev = (gx_device_memory *)dev;
+#define BUF_LONGS 100 /* arbitrary, >= 1 */
+#define BUF_BYTES (BUF_LONGS * ARCH_SIZEOF_LONG)
+ union b_ {
+ ulong l[BUF_LONGS];
+ byte b[BUF_BYTES];
+ } buf0, buf1, buf2, buf3;
+ mem_save_params_t save;
+ const gx_device_memory *mdproto = gdev_mem_device_for_bits(1);
+ uint plane_raster = bitmap_raster(w);
+ int br, bw, bh, cx, cy, cw, ch, ix, iy;
+
+ fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
+ MEM_SAVE_PARAMS(mdev, save);
+ MEM_SET_PARAMS(mdev, 1);
+ if (plane_raster > BUF_BYTES) {
+ br = BUF_BYTES;
+ bw = BUF_BYTES<<3;
+ bh = 1;
+ } else {
+ br = plane_raster;
+ bw = w;
+ bh = BUF_BYTES / plane_raster;
+ }
+ for (cy = y; cy < y + h; cy += ch) {
+ ch = min(bh, y + h - cy);
+ for (cx = x; cx < x + w; cx += cw) {
+ int sx = sourcex + cx - x;
+ const byte *source_base = base + sraster * (cy - y) + (sx>>1);
+
+ cw = min(bw, x + w - cx);
+ if ((sx & 1) == 0) {
+ for (iy = 0; iy < ch; ++iy) {
+ const byte *sptr = source_base;
+ byte *dptr0 = buf0.b + br * iy;
+ byte *dptr1 = buf1.b + br * iy;
+ byte *dptr2 = buf2.b + br * iy;
+ byte *dptr3 = buf3.b + br * iy;
+ byte roll = 0x80;
+ byte bc = 0;
+ byte bm = 0;
+ byte by = 0;
+ byte bk = 0;
+ ix = cw;
+ do {
+ byte b = *sptr++;
+ if (b & 0x80)
+ bc |= roll;
+ if (b & 0x40)
+ bm |= roll;
+ if (b & 0x20)
+ by |= roll;
+ if (b & 0x10)
+ bk |= roll;
+ roll >>= 1;
+ if (b & 0x08)
+ bc |= roll;
+ if (b & 0x04)
+ bm |= roll;
+ if (b & 0x02)
+ by |= roll;
+ if (b & 0x01)
+ bk |= roll;
+ roll >>= 1;
+ if (roll == 0) {
+ *dptr0++ = bc;
+ *dptr1++ = bm;
+ *dptr2++ = by;
+ *dptr3++ = bk;
+ bc = 0;
+ bm = 0;
+ by = 0;
+ bk = 0;
+ roll = 0x80;
+ }
+ ix -= 2;
+ } while (ix > 0);
+ if (roll != 0x80) {
+ *dptr0++ = bc;
+ *dptr1++ = bm;
+ *dptr2++ = by;
+ *dptr3++ = bk;
+ }
+ source_base += sraster;
+ }
+ } else {
+ for (iy = 0; iy < ch; ++iy) {
+ const byte *sptr = source_base;
+ byte *dptr0 = buf0.b + br * iy;
+ byte *dptr1 = buf1.b + br * iy;
+ byte *dptr2 = buf2.b + br * iy;
+ byte *dptr3 = buf3.b + br * iy;
+ byte roll = 0x80;
+ byte bc = 0;
+ byte bm = 0;
+ byte by = 0;
+ byte bk = 0;
+ byte b = *sptr++;
+ ix = cw;
+ goto loop_entry;
+ do {
+ b = *sptr++;
+ if (b & 0x80)
+ bc |= roll;
+ if (b & 0x40)
+ bm |= roll;
+ if (b & 0x20)
+ by |= roll;
+ if (b & 0x10)
+ bk |= roll;
+ roll >>= 1;
+ if (roll == 0) {
+ *dptr0++ = bc;
+ *dptr1++ = bm;
+ *dptr2++ = by;
+ *dptr3++ = bk;
+ bc = 0;
+ bm = 0;
+ by = 0;
+ bk = 0;
+ roll = 0x80;
+ }
+loop_entry:
+ if (b & 0x08)
+ bc |= roll;
+ if (b & 0x04)
+ bm |= roll;
+ if (b & 0x02)
+ by |= roll;
+ if (b & 0x01)
+ bk |= roll;
+ roll >>= 1;
+ ix -= 2;
+ } while (ix >= 0); /* ix == -2 means 1 extra done */
+ if ((ix == -2) && (roll == 0x40)) {
+ /* We did an extra one, and it was the last thing
+ * we did. Nothing to store. */
+ } else {
+ /* Flush the stored bytes */
+ *dptr0++ = bc;
+ *dptr1++ = bm;
+ *dptr2++ = by;
+ *dptr3++ = bk;
+ }
+ source_base += sraster;
+ }
+ }
+ dev_proc(mdproto, copy_mono)
+ (dev, buf0.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch,
+ (gx_color_index)0, (gx_color_index)1);
+ mdev->line_ptrs += mdev->height;
+ dev_proc(mdproto, copy_mono)
+ (dev, buf1.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch,
+ (gx_color_index)0, (gx_color_index)1);
+ mdev->line_ptrs += mdev->height;
+ dev_proc(mdproto, copy_mono)
+ (dev, buf2.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch,
+ (gx_color_index)0, (gx_color_index)1);
+ mdev->line_ptrs += mdev->height;
+ dev_proc(mdproto, copy_mono)
+ (dev, buf3.b, 0, br, gx_no_bitmap_id, cx, cy, cw, ch,
+ (gx_color_index)0, (gx_color_index)1);
+ mdev->line_ptrs -= 3*mdev->height;
+ }
+ }
+ MEM_RESTORE_PARAMS(mdev, save);
+ return 0;
+}
+
/* Copy a color bitmap. */
/* This is slow and messy. */
static int
More information about the gs-commits
mailing list