2 |
- |
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
|
|
|
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
|
|
|
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
|
|
|
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
|
|
|
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
|
|
|
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 |
}
|