1 /* Copyright (C) 1994, 1996, 1998, 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gdevm16.c,v 1.5 2002/08/22 07:12:28 henrys Exp $ */
18 /* 16-bit-per-pixel "memory" (stored bitmap) device */
19 #include "memory_.h"
20 #include "gx.h"
21 #include "gxdevice.h"
22 #include "gxdevmem.h" /* semi-public definitions */
23 #include "gdevmem.h" /* private definitions */
24
25 #undef chunk
26 #define chunk byte
27
28 /* The 16 bits are divided 5 for red, 6 for green, and 5 for blue. */
29 /* Note that the bits must always be kept in big-endian order. */
30
31 /* Procedures */
32 declare_mem_map_procs(mem_true16_map_rgb_color, mem_true16_map_color_rgb);
33 declare_mem_procs(mem_true16_copy_mono, mem_true16_copy_color, mem_true16_fill_rectangle);
34
35 /* The device descriptor. */
36 const gx_device_memory mem_true16_device =
37 mem_device("image16", 16, 0,
38 mem_true16_map_rgb_color, mem_true16_map_color_rgb,
39 mem_true16_copy_mono, mem_true16_copy_color,
40 mem_true16_fill_rectangle, mem_default_strip_copy_rop);
41
42 /* Map a r-g-b color to a color index. */
43 private gx_color_index
mem_true16_map_rgb_color(gx_device * dev,const gx_color_value cv[])44 mem_true16_map_rgb_color(gx_device * dev, const gx_color_value cv[])
45 {
46 return ((cv[0] >> (gx_color_value_bits - 5)) << 11) +
47 ((cv[1] >> (gx_color_value_bits - 6)) << 5) +
48 (cv[2] >> (gx_color_value_bits - 5));
49 }
50
51 /* Map a color index to a r-g-b color. */
52 private int
mem_true16_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])53 mem_true16_map_color_rgb(gx_device * dev, gx_color_index color,
54 gx_color_value prgb[3])
55 {
56 ushort value = color >> 11;
57
58 prgb[0] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4))
59 >> (16 - gx_color_value_bits);
60 value = (color >> 5) & 0x3f;
61 prgb[1] = ((value << 10) + (value << 4) + (value >> 2))
62 >> (16 - gx_color_value_bits);
63 value = color & 0x1f;
64 prgb[2] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4))
65 >> (16 - gx_color_value_bits);
66 return 0;
67 }
68
69 /* Convert x coordinate to byte offset in scan line. */
70 #undef x_to_byte
71 #define x_to_byte(x) ((x) << 1)
72
73 /* Fill a rectangle with a color. */
74 private int
mem_true16_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)75 mem_true16_fill_rectangle(gx_device * dev,
76 int x, int y, int w, int h, gx_color_index color)
77 {
78 gx_device_memory * const mdev = (gx_device_memory *)dev;
79 #if arch_is_big_endian
80 const ushort color16 = (ushort)color;
81 #else
82 const ushort color16 = (ushort)((color << 8) | (color >> 8));
83 #endif
84 declare_scan_ptr(dest);
85
86 fit_fill(dev, x, y, w, h);
87 setup_rect(dest);
88 if (w == 1) {
89 while (h-- > 0) {
90 *(ushort *)dest = color16;
91 inc_ptr(dest, draster);
92 }
93 } else if ((color16 >> 8) == (color16 & 0xff)) {
94 bytes_fill_rectangle(scan_line_base(mdev, y) + (x << 1), draster,
95 (byte)color, w << 1, h);
96 } else {
97 while (h-- > 0) {
98 ushort *pptr = (ushort *) dest;
99 int cnt = w;
100
101 for (; cnt >= 4; pptr += 4, cnt -= 4)
102 pptr[3] = pptr[2] = pptr[1] = pptr[0] = color16;
103 switch (cnt) {
104 case 3: pptr[2] = color16;
105 case 2: pptr[1] = color16;
106 case 1: pptr[0] = color16;
107 case 0: DO_NOTHING;
108 }
109 inc_ptr(dest, draster);
110 }
111 }
112 return 0;
113 }
114
115 /* Copy a monochrome bitmap. */
116 private int
mem_true16_copy_mono(gx_device * dev,const 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)117 mem_true16_copy_mono(gx_device * dev,
118 const byte * base, int sourcex, int sraster,
119 gx_bitmap_id id, int x, int y, int w, int h,
120 gx_color_index zero, gx_color_index one)
121 {
122 gx_device_memory * const mdev = (gx_device_memory *)dev;
123 #if arch_is_big_endian
124 const ushort zero16 = (ushort)zero;
125 const ushort one16 = (ushort)one;
126 #else
127 ushort zero16 = ((uint) (byte) zero << 8) + ((ushort) zero >> 8);
128 ushort one16 = ((uint) (byte) one << 8) + ((ushort) one >> 8);
129 #endif
130 const byte *line;
131 int first_bit;
132
133 declare_scan_ptr(dest);
134 fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
135 setup_rect(dest);
136 line = base + (sourcex >> 3);
137 first_bit = 0x80 >> (sourcex & 7);
138 while (h-- > 0) {
139 register ushort *pptr = (ushort *) dest;
140 const byte *sptr = line;
141 register int sbyte = *sptr++;
142 register int bit = first_bit;
143 int count = w;
144
145 do {
146 if (sbyte & bit) {
147 if (one != gx_no_color_index)
148 *pptr = one16;
149 } else {
150 if (zero != gx_no_color_index)
151 *pptr = zero16;
152 }
153 if ((bit >>= 1) == 0)
154 bit = 0x80, sbyte = *sptr++;
155 pptr++;
156 }
157 while (--count > 0);
158 line += sraster;
159 inc_ptr(dest, draster);
160 }
161 return 0;
162 }
163
164 /* Copy a color bitmap. */
165 private int
mem_true16_copy_color(gx_device * dev,const byte * base,int sourcex,int sraster,gx_bitmap_id id,int x,int y,int w,int h)166 mem_true16_copy_color(gx_device * dev,
167 const byte * base, int sourcex, int sraster, gx_bitmap_id id,
168 int x, int y, int w, int h)
169 {
170 gx_device_memory * const mdev = (gx_device_memory *)dev;
171
172 fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
173 mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h);
174 return 0;
175 }
176