386BSD 0.1 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Sat, 11 Apr 1992 13:42:32 +0000 (05:42 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Sat, 11 Apr 1992 13:42:32 +0000 (05:42 -0800)
Work on file usr/othersrc/public/ghostscript-2.4.1/gdevmem2.c

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.1

usr/othersrc/public/ghostscript-2.4.1/gdevmem2.c [new file with mode: 0644]

diff --git a/usr/othersrc/public/ghostscript-2.4.1/gdevmem2.c b/usr/othersrc/public/ghostscript-2.4.1/gdevmem2.c
new file mode 100644 (file)
index 0000000..02ad9c3
--- /dev/null
@@ -0,0 +1,511 @@
+/* Copyright (C) 1989, 1992 Aladdin Enterprises.  All rights reserved.
+   Distributed by Free Software Foundation, Inc.
+
+This file is part of Ghostscript.
+
+Ghostscript is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
+to anyone for the consequences of using it or for whether it serves any
+particular purpose or works at all, unless he says so in writing.  Refer
+to the Ghostscript General Public License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+Ghostscript, but only under the conditions described in the Ghostscript
+General Public License.  A copy of this license is supposed to have been
+given to you along with Ghostscript so you can know your rights and
+responsibilities.  It should be in a file named COPYING.  Among other
+things, the copyright notice and this notice must be preserved on all
+copies.  */
+
+/* gdevmem2.c */
+/* 8-and-more-bit-per-pixel "memory" (stored bitmap) devices */
+/* for Ghostscript library. */
+#include "memory_.h"
+#include "gs.h"
+#include "gxdevice.h"
+#include "gxdevmem.h"                  /* semi-public definitions */
+#include "gdevmem.h"                   /* private definitions */
+
+/* ------ Generic procedures ------ */
+
+/* Copy a rectangle of bytes from a source to a destination. */
+#undef chunk
+#define chunk byte
+private int
+copy_byte_rect(gx_device_memory *dev, const byte *source, int sraster,
+  int offset, int y, int byte_count, int h)
+{      uint draster = dev->raster;
+       byte *dest = scan_line_base(dev, y) + offset;
+       while ( h-- > 0 )
+          {    memcpy(dest, source, byte_count);
+               source += sraster;
+               dest += draster;
+          }
+       return 0;
+}
+
+/* Map a r-g-b color to a color index. */
+/* This requires searching the palette. */
+gx_color_index
+mem_mapped_map_rgb_color(gx_device *dev, gx_color_value r, gx_color_value g,
+  gx_color_value b)
+{      byte br = gx_color_value_to_byte(r);
+       byte bg = gx_color_value_to_byte(g);
+       byte bb = gx_color_value_to_byte(b);
+       register byte *pptr = mdev->palette;
+       int cnt = mdev->palette_size;
+       byte *which;
+       int best = 256*3;
+       while ( cnt-- > 0 )
+          {    register int diff = *pptr - br;
+               if ( diff < 0 ) diff = -diff;
+               if ( diff < best )      /* quick rejection */
+                  {    int dg = pptr[1] - bg;
+                       if ( dg < 0 ) dg = -dg;
+                       if ( (diff += dg) < best )      /* quick rejection */
+                          {    int db = pptr[2] - bb;
+                               if ( db < 0 ) db = -db;
+                               if ( (diff += db) < best )
+                                       which = pptr, best = diff;
+                          }
+                  }
+               pptr += 3;
+          }
+       return (gx_color_index)((which - mdev->palette) / 3);
+}
+
+/* Map a color index to a r-g-b color. */
+int
+mem_mapped_map_color_rgb(gx_device *dev, gx_color_index color,
+  gx_color_value prgb[3])
+{      byte *pptr = mdev->palette + (int)color * 3;
+       prgb[0] = gx_color_value_from_byte(pptr[0]);
+       prgb[1] = gx_color_value_from_byte(pptr[1]);
+       prgb[2] = gx_color_value_from_byte(pptr[2]);
+       return 0;
+}
+
+/* ------ Mapped 8-bit color ------ */
+
+/* Procedures */
+declare_mem_procs(mem_mapped8_copy_mono, mem_mapped8_copy_color, mem_mapped8_fill_rectangle);
+
+/* The device descriptor. */
+private gx_device_procs mem_mapped8_procs =
+  mem_procs(mem_mapped_map_rgb_color, mem_mapped_map_color_rgb,
+    mem_mapped8_copy_mono, mem_mapped8_copy_color, mem_mapped8_fill_rectangle);
+
+/* The instance is public. */
+gx_device_memory mem_mapped8_color_device =
+  mem_device("image(8)", 8, mem_mapped8_procs);
+
+/* Convert x coordinate to byte offset in scan line. */
+#undef x_to_byte
+#define x_to_byte(x) (x)
+
+/* Fill a rectangle with a color. */
+private int
+mem_mapped8_fill_rectangle(gx_device *dev,
+  int x, int y, int w, int h, gx_color_index color)
+{      declare_scan_ptr(dest);
+       check_rect();
+       setup_rect(dest);
+       while ( h-- > 0 )
+          {    memset(dest, (byte)color, w);
+               inc_chunk_ptr(dest, draster);
+          }
+       return 0;
+}
+
+/* Copy a monochrome bitmap. */
+private int
+mem_mapped8_copy_mono(gx_device *dev,
+  byte *base, int sourcex, int sraster, gx_bitmap_id id,
+  int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
+{      byte *line;
+       int first_bit;
+       declare_scan_ptr(dest);
+       check_rect();
+       setup_rect(dest);
+       line = base + (sourcex >> 3);
+       first_bit = 0x80 >> (sourcex & 7);
+       while ( h-- > 0 )
+          {    register byte *pptr = dest;
+               byte *sptr = line;
+               register int sbyte = *sptr;
+               register uint bit = first_bit;
+               int count = w;
+#define is_color(c) ((int)(c) != (int)gx_no_color_index)
+#define next_bit()\
+  if ( (bit >>= 1) == 0 ) bit = 0x80, sbyte = *++sptr;\
+  pptr++
+               if ( is_color(one) )
+                  {    if ( is_color(zero) )
+                          {    /* Optimize halftone coloring */
+                               do
+                                  {    *pptr = (sbyte & bit ? (byte)one :
+                                                (byte)zero);
+                                       next_bit();
+                                  }
+                               while ( --count > 0 );
+                          }
+                       else
+                          {    /* Optimize stenciling */
+                               do
+                                  {    if ( sbyte & bit )
+                                         *pptr = (byte)one;
+                                       next_bit();
+                                  }
+                               while ( --count > 0 );
+                          }
+                  }
+               else if ( is_color(zero) )
+                  {    do
+                          {    if ( !(sbyte & bit) )
+                                 *pptr = (byte)zero;
+                               next_bit();
+                          }
+                       while ( --count > 0 );
+                  }
+#undef next_bit
+#undef is_color
+               line += sraster;
+               inc_chunk_ptr(dest, draster);
+          }
+       return 0;
+}
+
+/* Copy a color bitmap. */
+private int
+mem_mapped8_copy_color(gx_device *dev,
+  byte *base, int sourcex, int sraster, gx_bitmap_id id,
+  int x, int y, int w, int h)
+{      check_rect();
+       return copy_byte_rect(mdev, base + x_to_byte(sourcex), sraster,
+               x_to_byte(x), y, x_to_byte(w), h);
+}
+
+/* ------ 16-bit true color ------ */
+/* The 16 bits are divided 5 for red, 6 for green, and 5 for blue. */
+
+/* Procedures */
+declare_mem_map_procs(mem_true16_map_rgb_color, mem_true16_map_color_rgb);
+declare_mem_procs(mem_true16_copy_mono, mem_true16_copy_color, mem_true16_fill_rectangle);
+
+/* The device descriptor. */
+private gx_device_procs mem_true16_procs =
+  mem_procs(mem_true16_map_rgb_color, mem_true16_map_color_rgb,
+    mem_true16_copy_mono, mem_true16_copy_color, mem_true16_fill_rectangle);
+
+/* The instance is public. */
+gx_device_memory mem_true16_color_device =
+  mem_device("image(16)", 16, mem_true16_procs);
+
+/* Map a r-g-b color to a color index. */
+private gx_color_index
+mem_true16_map_rgb_color(gx_device *dev, gx_color_value r, gx_color_value g,
+  gx_color_value b)
+{      return ((r >> (gx_color_value_bits - 5)) << 11) +
+               ((g >> (gx_color_value_bits - 6)) << 5) +
+               (b >> (gx_color_value_bits - 5));
+}
+
+/* Map a color index to a r-g-b color. */
+private int
+mem_true16_map_color_rgb(gx_device *dev, gx_color_index color,
+  gx_color_value prgb[3])
+{      ushort value;
+       value = color >> 11;
+       prgb[0] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4)) >> (16 - gx_color_value_bits);
+       value = (color >> 6) & 0x7f;
+       prgb[1] = ((value << 10) + (value << 4) + (value >> 2)) >> (16 - gx_color_value_bits);
+       value = color & 0x3f;
+       prgb[2] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4)) >> (16 - gx_color_value_bits);
+       return 0;
+}
+
+/* Convert x coordinate to byte offset in scan line. */
+#undef x_to_byte
+#define x_to_byte(x) ((x) << 1)
+
+/* Fill a rectangle with a color. */
+private int
+mem_true16_fill_rectangle(gx_device *dev,
+  int x, int y, int w, int h, gx_color_index color)
+{      declare_scan_ptr(dest);
+       check_rect();
+       setup_rect(dest);
+       while ( h-- > 0 )
+          {    ushort *pptr = (ushort *)dest;
+               int cnt = w;
+               do { *pptr++ = (ushort)color; } while ( --cnt > 0 );
+               inc_chunk_ptr(dest, draster);
+          }
+       return 0;
+}
+
+/* Copy a monochrome bitmap. */
+private int
+mem_true16_copy_mono(gx_device *dev,
+  byte *base, int sourcex, int sraster, gx_bitmap_id id,
+  int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
+{      byte *line;
+       int first_bit;
+       declare_scan_ptr(dest);
+       check_rect();
+       setup_rect(dest);
+       line = base + (sourcex >> 3);
+       first_bit = 0x80 >> (sourcex & 7);
+       while ( h-- > 0 )
+          {    register ushort *pptr = (ushort *)dest;
+               byte *sptr = line;
+               register int sbyte = *sptr++;
+               register int bit = first_bit;
+               int count = w;
+               do
+                  {    if ( sbyte & bit )
+                          {    if ( one != gx_no_color_index )
+                                 *pptr = (ushort)one;
+                          }
+                       else
+                          {    if ( zero != gx_no_color_index )
+                                 *pptr = (ushort)zero;
+                          }
+                       if ( (bit >>= 1) == 0 )
+                               bit = 0x80, sbyte = *sptr++;
+                       pptr++;
+                  }
+               while ( --count > 0 );
+               line += sraster;
+               inc_chunk_ptr(dest, draster);
+          }
+       return 0;
+}
+
+/* Copy a color bitmap. */
+private int
+mem_true16_copy_color(gx_device *dev,
+  byte *base, int sourcex, int sraster, gx_bitmap_id id,
+  int x, int y, int w, int h)
+{      check_rect();
+       return copy_byte_rect(mdev, base + x_to_byte(sourcex), sraster,
+               x_to_byte(x), y, x_to_byte(w), h);
+}
+
+/* ------ 24- or 32-bit true color ------ */
+
+/* Procedures */
+declare_mem_map_procs(mem_true_map_rgb_color, mem_true_map_color_rgb);
+
+/* The device descriptor. */
+#define mem_true_procs(copy_mono, copy_color, fill_rectangle)\
+  mem_procs(mem_true_map_rgb_color, mem_true_map_color_rgb,\
+    copy_mono, copy_color, fill_rectangle)
+
+/* We want the bytes of a color always to be in the order -,r,g,b, */
+/* but we want to manipulate colors as longs.  This requires careful */
+/* handling to be byte-order independent. */
+#define color_byte(cx,i) (((byte *)&(cx))[i])
+
+/* Map a r-g-b color to a color index. */
+private gx_color_index
+mem_true_map_rgb_color(gx_device *dev, gx_color_value r, gx_color_value g,
+  gx_color_value b)
+{      return gx_color_value_to_byte(b) +
+              ((uint)gx_color_value_to_byte(g) << 8) +
+              ((ulong)gx_color_value_to_byte(r) << 16);
+}
+
+/* Map a color index to a r-g-b color. */
+private int
+mem_true_map_color_rgb(gx_device *dev, gx_color_index color,
+  gx_color_value prgb[3])
+{      prgb[0] = gx_color_value_from_byte(color >> 16);
+       prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff);
+       prgb[2] = gx_color_value_from_byte(color & 0xff);
+       return 0;
+}
+
+/* ------ 24-bit color ------ */
+/* 24-bit takes less space than 32-bit, but is slower. */
+
+/* Procedures */
+declare_mem_procs(mem_true24_copy_mono, mem_true24_copy_color, mem_true24_fill_rectangle);
+
+/* The device descriptor. */
+private gx_device_procs mem_true24_procs =
+  mem_true_procs(mem_true24_copy_mono, mem_true24_copy_color,
+    mem_true24_fill_rectangle);
+gx_device_memory mem_true24_color_device =
+  mem_device("image(24)", 24, mem_true24_procs);
+
+/* Convert x coordinate to byte offset in scan line. */
+#undef x_to_byte
+#define x_to_byte(x) ((x) * 3)
+
+/* Unpack a color into its bytes. */
+#define declare_unpack_color(r, g, b, color)\
+       byte r = (byte)(color >> 16);\
+       byte g = (byte)((uint)color >> 8);\
+       byte b = (byte)color
+#define put3(ptr, r, g, b)\
+       ptr[0] = r, ptr[1] = g, ptr[2] = b
+
+/* Fill a rectangle with a color. */
+private int
+mem_true24_fill_rectangle(gx_device *dev,
+  int x, int y, int w, int h, gx_color_index color)
+{      declare_unpack_color(r, g, b, color);
+       declare_scan_ptr(dest);
+       check_rect();
+       setup_rect(dest);
+       while ( h-- > 0 )
+          {    register int cnt = w;
+               register byte *pptr = dest;
+               do { put3(pptr, r, g, b); pptr += 3; } while ( --cnt > 0 );
+               inc_chunk_ptr(dest, draster);
+          }
+       return 0;
+}
+
+/* Copy a monochrome bitmap. */
+private int
+mem_true24_copy_mono(gx_device *dev,
+  byte *base, int sourcex, int sraster, gx_bitmap_id id,
+  int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
+{      byte *line;
+       int first_bit;
+       declare_unpack_color(r0, g0, b0, zero);
+       declare_unpack_color(r1, g1, b1, one);
+       declare_scan_ptr(dest);
+       check_rect();
+       setup_rect(dest);
+       line = base + (sourcex >> 3);
+       first_bit = 0x80 >> (sourcex & 7);
+       while ( h-- > 0 )
+          {    register byte *pptr = dest;
+               byte *sptr = line;
+               register int sbyte = *sptr++;
+               register int bit = first_bit;
+               int count = w;
+               do
+                  {    if ( sbyte & bit )
+                          {    if ( one != gx_no_color_index )
+                                 put3(pptr, r1, g1, b1);
+                          }
+                       else
+                          {    if ( zero != gx_no_color_index )
+                                 put3(pptr, r0, g0, b0);
+                          }
+                       pptr += 3;
+                       if ( (bit >>= 1) == 0 )
+                               bit = 0x80, sbyte = *sptr++;
+                  }
+               while ( --count > 0 );
+               line += sraster;
+               inc_chunk_ptr(dest, draster);
+          }
+       return 0;
+}
+
+/* Copy a color bitmap. */
+private int
+mem_true24_copy_color(gx_device *dev,
+  byte *base, int sourcex, int sraster, gx_bitmap_id id,
+  int x, int y, int w, int h)
+{      check_rect();
+       return copy_byte_rect(mdev, base + x_to_byte(sourcex), sraster,
+               x_to_byte(x), y, x_to_byte(w), h);
+}
+
+/* ------ 32-bit color ------ */
+
+/* Procedures */
+declare_mem_procs(mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle);
+
+/* The device descriptor. */
+private gx_device_procs mem_true32_procs =
+  mem_true_procs(mem_true32_copy_mono, mem_true32_copy_color,
+    mem_true32_fill_rectangle);
+gx_device_memory mem_true32_color_device =
+  mem_device("image(32)", 32, mem_true32_procs);
+
+/* Convert x coordinate to byte offset in scan line. */
+#undef x_to_byte
+#define x_to_byte(x) ((x) << 2)
+
+/* Swap the bytes of a color if needed. */
+#if arch_is_big_endian
+#  define arrange_bytes(color) (color)
+#else
+#  define arrange_bytes(color)\
+    (((color) >> 24) + (((color) >> 16) & 0xff00) +\
+     (((color) & 0xff00) << 8) + ((color) << 24))
+#endif
+
+/* Fill a rectangle with a color. */
+private int
+mem_true32_fill_rectangle(gx_device *dev,
+  int x, int y, int w, int h, gx_color_index color)
+{      gx_color_index a_color = arrange_bytes(color);
+       declare_scan_ptr(dest);
+       check_rect();
+       setup_rect(dest);
+       while ( h-- > 0 )
+          {    gx_color_index *pptr = (gx_color_index *)dest;
+               int cnt = w;
+               do { *pptr++ = a_color; } while ( --cnt > 0 );
+               inc_chunk_ptr(dest, draster);
+          }
+       return 0;
+}
+
+/* Copy a monochrome bitmap. */
+private int
+mem_true32_copy_mono(gx_device *dev,
+  byte *base, int sourcex, int sraster, gx_bitmap_id id,
+  int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
+{      gx_color_index a_zero = arrange_bytes(zero);
+       gx_color_index a_one = arrange_bytes(one);
+       byte *line;
+       int first_bit;
+       declare_scan_ptr(dest);
+       check_rect();
+       setup_rect(dest);
+       line = base + (sourcex >> 3);
+       first_bit = 0x80 >> (sourcex & 7);
+       while ( h-- > 0 )
+          {    register gx_color_index *pptr = (gx_color_index *)dest;
+               byte *sptr = line;
+               register int sbyte = *sptr++;
+               register int bit = first_bit;
+               int count = w;
+               do
+                  {    if ( sbyte & bit )
+                          {    if ( one != gx_no_color_index )
+                                 *pptr = a_one;
+                          }
+                       else
+                          {    if ( zero != gx_no_color_index )
+                                 *pptr = a_zero;
+                          }
+                       if ( (bit >>= 1) == 0 )
+                               bit = 0x80, sbyte = *sptr++;
+                       pptr++;
+                  }
+               while ( --count > 0 );
+               line += sraster;
+               inc_chunk_ptr(dest, draster);
+          }
+       return 0;
+}
+
+/* Copy a color bitmap. */
+private int
+mem_true32_copy_color(gx_device *dev,
+  byte *base, int sourcex, int sraster, gx_bitmap_id id,
+  int x, int y, int w, int h)
+{      check_rect();
+       return copy_byte_rect(mdev, base + x_to_byte(sourcex), sraster,
+               x_to_byte(x), y, x_to_byte(w), h);
+}