2 |
- |
1 |
/* Copyright (C) 1992, 1993, 1994, 1997, 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: gdevmgr.c,v 1.8 2005/01/19 00:24:07 dan Exp $*/
|
|
|
18 |
/* MGR device driver */
|
|
|
19 |
#include "gdevprn.h"
|
|
|
20 |
#include "gdevpccm.h"
|
|
|
21 |
#include "gdevmgr.h"
|
|
|
22 |
|
|
|
23 |
/* Structure for MGR devices, which extend the generic printer device. */
|
|
|
24 |
struct gx_device_mgr_s {
|
|
|
25 |
gx_device_common;
|
|
|
26 |
gx_prn_device_common;
|
|
|
27 |
/* Add MGR specific variables */
|
|
|
28 |
int mgr_depth;
|
|
|
29 |
};
|
|
|
30 |
typedef struct gx_device_mgr_s gx_device_mgr;
|
|
|
31 |
|
|
|
32 |
static struct nclut clut[256];
|
|
|
33 |
|
|
|
34 |
private unsigned int clut2mgr(int, int);
|
|
|
35 |
private void swap_bwords(unsigned char *, int);
|
|
|
36 |
|
|
|
37 |
/* ------ The device descriptors ------ */
|
|
|
38 |
|
|
|
39 |
/*
|
|
|
40 |
* Default X and Y resolution.
|
|
|
41 |
*/
|
|
|
42 |
#define X_DPI 72
|
|
|
43 |
#define Y_DPI 72
|
|
|
44 |
|
|
|
45 |
/* Macro for generating MGR device descriptors. */
|
|
|
46 |
#define mgr_prn_device(procs, dev_name, num_comp, depth, mgr_depth,\
|
|
|
47 |
max_gray, max_rgb, dither_gray, dither_rgb, print_page)\
|
|
|
48 |
{ prn_device_body(gx_device_mgr, procs, dev_name,\
|
|
|
49 |
DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, X_DPI, Y_DPI,\
|
|
|
50 |
0, 0, 0, 0,\
|
|
|
51 |
num_comp, depth, max_gray, max_rgb, dither_gray, dither_rgb,\
|
|
|
52 |
print_page),\
|
|
|
53 |
mgr_depth\
|
|
|
54 |
}
|
|
|
55 |
|
|
|
56 |
/* For all mgr variants we do some extra things at opening time. */
|
|
|
57 |
/* private dev_proc_open_device(gdev_mgr_open); */
|
|
|
58 |
#define gdev_mgr_open gdev_prn_open /* no we don't! */
|
|
|
59 |
|
|
|
60 |
/* And of course we need our own print-page routines. */
|
|
|
61 |
private dev_proc_print_page(mgr_print_page);
|
|
|
62 |
private dev_proc_print_page(mgrN_print_page);
|
|
|
63 |
private dev_proc_print_page(cmgrN_print_page);
|
|
|
64 |
|
|
|
65 |
/* The device procedures */
|
|
|
66 |
private gx_device_procs mgr_procs =
|
|
|
67 |
prn_procs(gdev_mgr_open, gdev_prn_output_page, gdev_prn_close);
|
|
|
68 |
private gx_device_procs mgrN_procs =
|
|
|
69 |
prn_color_procs(gdev_mgr_open, gdev_prn_output_page, gdev_prn_close,
|
|
|
70 |
gx_default_gray_map_rgb_color, gx_default_gray_map_color_rgb);
|
|
|
71 |
private gx_device_procs cmgr4_procs =
|
|
|
72 |
prn_color_procs(gdev_mgr_open, gdev_prn_output_page, gdev_prn_close,
|
|
|
73 |
pc_4bit_map_rgb_color, pc_4bit_map_color_rgb);
|
|
|
74 |
private gx_device_procs cmgr8_procs =
|
|
|
75 |
prn_color_procs(gdev_mgr_open, gdev_prn_output_page, gdev_prn_close,
|
|
|
76 |
mgr_8bit_map_rgb_color, mgr_8bit_map_color_rgb);
|
|
|
77 |
|
|
|
78 |
/* The device descriptors themselves */
|
|
|
79 |
gx_device_mgr far_data gs_mgrmono_device =
|
|
|
80 |
mgr_prn_device( mgr_procs, "mgrmono", 1, 1, 1, 1, 0, 2, 0, mgr_print_page);
|
|
|
81 |
gx_device_mgr far_data gs_mgrgray2_device =
|
|
|
82 |
mgr_prn_device(mgrN_procs, "mgrgray2",1, 8, 2, 255, 0, 4, 0, mgrN_print_page);
|
|
|
83 |
gx_device_mgr far_data gs_mgrgray4_device =
|
|
|
84 |
mgr_prn_device(mgrN_procs, "mgrgray4",1, 8, 4, 255, 0,16, 0, mgrN_print_page);
|
|
|
85 |
gx_device_mgr far_data gs_mgrgray8_device =
|
|
|
86 |
mgr_prn_device(mgrN_procs, "mgrgray8",1, 8, 8, 255, 0, 0, 0, mgrN_print_page);
|
|
|
87 |
gx_device_mgr far_data gs_mgr4_device =
|
|
|
88 |
mgr_prn_device(cmgr4_procs, "mgr4", 3, 8, 4, 1, 1, 2, 2, cmgrN_print_page);
|
|
|
89 |
gx_device_mgr far_data gs_mgr8_device =
|
|
|
90 |
mgr_prn_device(cmgr8_procs, "mgr8", 3, 8, 8, 255, 255, 6, 5, cmgrN_print_page);
|
|
|
91 |
|
|
|
92 |
/* ------ Internal routines ------ */
|
|
|
93 |
|
|
|
94 |
/* Define a "cursor" that keeps track of where we are in the page. */
|
|
|
95 |
typedef struct mgr_cursor_s {
|
|
|
96 |
gx_device_mgr *dev;
|
|
|
97 |
int bpp; /* bits per pixel */
|
|
|
98 |
uint line_size; /* bytes per scan line */
|
|
|
99 |
byte *data; /* output row buffer */
|
|
|
100 |
int lnum; /* row within page */
|
|
|
101 |
} mgr_cursor;
|
|
|
102 |
|
|
|
103 |
/* Begin an MGR output page. */
|
|
|
104 |
/* Write the header information and initialize the cursor. */
|
|
|
105 |
private int
|
|
|
106 |
mgr_begin_page(gx_device_mgr *bdev, FILE *pstream, mgr_cursor *pcur)
|
|
|
107 |
{ struct b_header head;
|
|
|
108 |
uint line_size =
|
|
|
109 |
gdev_prn_raster((gx_device_printer *)bdev) + 3;
|
|
|
110 |
byte *data = (byte *)gs_malloc(bdev->memory, line_size, 1, "mgr_begin_page");
|
|
|
111 |
if ( data == 0 )
|
|
|
112 |
return_error(gs_error_VMerror);
|
|
|
113 |
|
|
|
114 |
/* Write the header */
|
|
|
115 |
B_PUTHDR8(&head, bdev->width, bdev->height, bdev->mgr_depth);
|
|
|
116 |
fprintf(pstream, "");
|
|
|
117 |
if ( fwrite(&head, 1, sizeof(head), pstream) < sizeof(head) )
|
|
|
118 |
return_error(gs_error_ioerror);
|
|
|
119 |
fflush(pstream);
|
|
|
120 |
|
|
|
121 |
/* Initialize the cursor. */
|
|
|
122 |
pcur->dev = bdev;
|
|
|
123 |
pcur->bpp = bdev->color_info.depth;
|
|
|
124 |
pcur->line_size = line_size;
|
|
|
125 |
pcur->data = data;
|
|
|
126 |
pcur->lnum = 0;
|
|
|
127 |
return 0;
|
|
|
128 |
}
|
|
|
129 |
|
|
|
130 |
/* Advance to the next row. Return 0 if more, 1 if done. */
|
|
|
131 |
private int
|
|
|
132 |
mgr_next_row(mgr_cursor *pcur)
|
|
|
133 |
{ if ( pcur->lnum >= pcur->dev->height )
|
|
|
134 |
{ gs_free(((gx_device_printer *)pcur->dev)->memory,
|
|
|
135 |
(char *)pcur->data, pcur->line_size, 1,
|
|
|
136 |
"mgr_next_row(done)");
|
|
|
137 |
return 1;
|
|
|
138 |
}
|
|
|
139 |
gdev_prn_copy_scan_lines((gx_device_printer *)pcur->dev,
|
|
|
140 |
pcur->lnum++, pcur->data, pcur->line_size);
|
|
|
141 |
return 0;
|
|
|
142 |
}
|
|
|
143 |
|
|
|
144 |
/* ------ Individual page printing routines ------ */
|
|
|
145 |
|
|
|
146 |
#define bdev ((gx_device_mgr *)pdev)
|
|
|
147 |
|
|
|
148 |
/* Print a monochrome page. */
|
|
|
149 |
private int
|
|
|
150 |
mgr_print_page(gx_device_printer *pdev, FILE *pstream)
|
|
|
151 |
{ mgr_cursor cur;
|
|
|
152 |
int mgr_wide;
|
|
|
153 |
int code = mgr_begin_page(bdev, pstream, &cur);
|
|
|
154 |
if ( code < 0 ) return code;
|
|
|
155 |
|
|
|
156 |
mgr_wide = bdev->width;
|
|
|
157 |
if (mgr_wide & 7)
|
|
|
158 |
mgr_wide += 8 - (mgr_wide & 7);
|
|
|
159 |
|
|
|
160 |
while ( !(code = mgr_next_row(&cur)) )
|
|
|
161 |
{ if ( fwrite(cur.data, sizeof(char), mgr_wide / 8, pstream) <
|
|
|
162 |
mgr_wide / 8)
|
|
|
163 |
return_error(gs_error_ioerror);
|
|
|
164 |
}
|
|
|
165 |
return (code < 0 ? code : 0);
|
|
|
166 |
}
|
|
|
167 |
|
|
|
168 |
|
|
|
169 |
/* Print a gray-mapped page. */
|
|
|
170 |
static unsigned char bgreytable[16], bgreybacktable[16];
|
|
|
171 |
static unsigned char bgrey256table[256], bgrey256backtable[256];
|
|
|
172 |
private int
|
|
|
173 |
mgrN_print_page(gx_device_printer *pdev, FILE *pstream)
|
|
|
174 |
{ mgr_cursor cur;
|
|
|
175 |
int i = 0, j, k, mgr_wide;
|
|
|
176 |
uint mgr_line_size;
|
|
|
177 |
byte *bp, *data = NULL, *dp;
|
|
|
178 |
|
|
|
179 |
int code = mgr_begin_page(bdev, pstream, &cur);
|
|
|
180 |
if ( code < 0 ) return code;
|
|
|
181 |
|
|
|
182 |
mgr_wide = bdev->width;
|
|
|
183 |
if ( bdev->mgr_depth == 2 && mgr_wide & 3 )
|
|
|
184 |
mgr_wide += 4 - (mgr_wide & 3);
|
|
|
185 |
if ( bdev->mgr_depth == 4 && mgr_wide & 1 )
|
|
|
186 |
mgr_wide++;
|
|
|
187 |
mgr_line_size = mgr_wide / ( 8 / bdev->mgr_depth );
|
|
|
188 |
|
|
|
189 |
if ( bdev->mgr_depth == 4 )
|
|
|
190 |
for ( i = 0; i < 16; i++ ) {
|
|
|
191 |
bgreytable[i] = mgrlut[LUT_BGREY][RGB_RED][i];
|
|
|
192 |
bgreybacktable[bgreytable[i]] = i;
|
|
|
193 |
}
|
|
|
194 |
|
|
|
195 |
if ( bdev->mgr_depth == 8 ) {
|
|
|
196 |
for ( i = 0; i < 16; i++ ) {
|
|
|
197 |
bgrey256table[i] = mgrlut[LUT_BGREY][RGB_RED][i] << 4;
|
|
|
198 |
bgrey256backtable[bgrey256table[i]] = i;
|
|
|
199 |
}
|
|
|
200 |
for ( i = 16,j = 0; i < 256; i++ ) {
|
|
|
201 |
for ( k = 0; k < 16; k++ )
|
|
|
202 |
if ( j == mgrlut[LUT_BGREY][RGB_RED][k] << 4 ) {
|
|
|
203 |
j++;
|
|
|
204 |
break;
|
|
|
205 |
}
|
|
|
206 |
bgrey256table[i] = j;
|
|
|
207 |
bgrey256backtable[j++] = i;
|
|
|
208 |
}
|
|
|
209 |
}
|
|
|
210 |
|
|
|
211 |
if ( bdev->mgr_depth != 8 )
|
|
|
212 |
data = (byte *)gs_malloc(pdev->memory, mgr_line_size, 1, "mgrN_print_page");
|
|
|
213 |
|
|
|
214 |
while ( !(code = mgr_next_row(&cur)) )
|
|
|
215 |
{
|
|
|
216 |
switch (bdev->mgr_depth) {
|
|
|
217 |
case 2:
|
|
|
218 |
for (i = 0,dp = data,bp = cur.data; i < mgr_line_size; i++) {
|
|
|
219 |
*dp = *(bp++) & 0xc0;
|
|
|
220 |
*dp |= (*(bp++) & 0xc0) >> 2;
|
|
|
221 |
*dp |= (*(bp++) & 0xc0) >> 4;
|
|
|
222 |
*(dp++) |= (*(bp++) & 0xc0) >> 6;
|
|
|
223 |
}
|
|
|
224 |
if ( fwrite(data, sizeof(byte), mgr_line_size, pstream) < mgr_line_size )
|
|
|
225 |
return_error(gs_error_ioerror);
|
|
|
226 |
break;
|
|
|
227 |
|
|
|
228 |
case 4:
|
|
|
229 |
for (i = 0,dp = data, bp = cur.data; i < mgr_line_size; i++) {
|
|
|
230 |
*dp = bgreybacktable[*(bp++) >> 4] << 4;
|
|
|
231 |
*(dp++) |= bgreybacktable[*(bp++) >> 4];
|
|
|
232 |
}
|
|
|
233 |
if ( fwrite(data, sizeof(byte), mgr_line_size, pstream) < mgr_line_size )
|
|
|
234 |
return_error(gs_error_ioerror);
|
|
|
235 |
break;
|
|
|
236 |
|
|
|
237 |
case 8:
|
|
|
238 |
for (i = 0,bp = cur.data; i < mgr_line_size; i++, bp++)
|
|
|
239 |
*bp = bgrey256backtable[*bp];
|
|
|
240 |
if ( fwrite(cur.data, sizeof(cur.data[0]), mgr_line_size, pstream)
|
|
|
241 |
< mgr_line_size )
|
|
|
242 |
return_error(gs_error_ioerror);
|
|
|
243 |
break;
|
|
|
244 |
}
|
|
|
245 |
}
|
|
|
246 |
if (bdev->mgr_depth != 8)
|
|
|
247 |
gs_free(bdev->memory, (char *)data, mgr_line_size, 1, "mgrN_print_page(done)");
|
|
|
248 |
|
|
|
249 |
if (bdev->mgr_depth == 2) {
|
|
|
250 |
for (i = 0; i < 4; i++) {
|
|
|
251 |
clut[i].colnum = i;
|
|
|
252 |
clut[i].red = clut[i].green = clut[i].blue = clut2mgr(i, 2);
|
|
|
253 |
}
|
|
|
254 |
}
|
|
|
255 |
if (bdev->mgr_depth == 4) {
|
|
|
256 |
for (i = 0; i < 16; i++) {
|
|
|
257 |
clut[i].colnum = i;
|
|
|
258 |
clut[i].red = clut[i].green = clut[i].blue = clut2mgr(bgreytable[i], 4);
|
|
|
259 |
}
|
|
|
260 |
}
|
|
|
261 |
if (bdev->mgr_depth == 8) {
|
|
|
262 |
for (i = 0; i < 256; i++) {
|
|
|
263 |
clut[i].colnum = i;
|
|
|
264 |
clut[i].red = clut[i].green = clut[i].blue = clut2mgr(bgrey256table[i], 8);
|
|
|
265 |
}
|
|
|
266 |
}
|
|
|
267 |
#if !arch_is_big_endian
|
|
|
268 |
swap_bwords( (unsigned char *) clut, sizeof( struct nclut ) * i );
|
|
|
269 |
#endif
|
|
|
270 |
if ( fwrite(&clut, sizeof(struct nclut), i, pstream) < i )
|
|
|
271 |
return_error(gs_error_ioerror);
|
|
|
272 |
return (code < 0 ? code : 0);
|
|
|
273 |
}
|
|
|
274 |
|
|
|
275 |
/* Print a color page. */
|
|
|
276 |
private int
|
|
|
277 |
cmgrN_print_page(gx_device_printer *pdev, FILE *pstream)
|
|
|
278 |
{ mgr_cursor cur;
|
|
|
279 |
int i = 0, j, mgr_wide, r, g, b, colors8 = 0;
|
|
|
280 |
uint mgr_line_size;
|
|
|
281 |
byte *bp, *data, *dp;
|
|
|
282 |
ushort prgb[3];
|
|
|
283 |
unsigned char table[256], backtable[256];
|
|
|
284 |
|
|
|
285 |
int code = mgr_begin_page(bdev, pstream, &cur);
|
|
|
286 |
if ( code < 0 ) return code;
|
|
|
287 |
|
|
|
288 |
mgr_wide = bdev->width;
|
|
|
289 |
if (bdev->mgr_depth == 4 && mgr_wide & 1)
|
|
|
290 |
mgr_wide++;
|
|
|
291 |
mgr_line_size = mgr_wide / (8 / bdev->mgr_depth);
|
|
|
292 |
data = (byte *)gs_malloc(pdev->memory, mgr_line_size, 1, "cmgrN_print_page");
|
|
|
293 |
|
|
|
294 |
if ( bdev->mgr_depth == 8 ) {
|
|
|
295 |
memset( table, 0, sizeof(table) );
|
|
|
296 |
for ( r = 0; r <= 6; r++ )
|
|
|
297 |
for ( g = 0; g <= 6; g++ )
|
|
|
298 |
for ( b = 0; b <= 6; b++ )
|
|
|
299 |
if ( r == g && g == b )
|
|
|
300 |
table[ r + (256-7) ] = 1;
|
|
|
301 |
else
|
|
|
302 |
table[ (r << 5) + (g << 2) + (b >> 1) ] = 1;
|
|
|
303 |
for ( i = j = 0; i < sizeof(table); i++ )
|
|
|
304 |
if ( table[i] == 1 ) {
|
|
|
305 |
backtable[i] = j;
|
|
|
306 |
table[j++] = i;
|
|
|
307 |
}
|
|
|
308 |
colors8 = j;
|
|
|
309 |
}
|
|
|
310 |
while ( !(code = mgr_next_row(&cur)) )
|
|
|
311 |
{
|
|
|
312 |
switch (bdev->mgr_depth) {
|
|
|
313 |
case 4:
|
|
|
314 |
for (i = 0,dp = data, bp = cur.data; i < mgr_line_size; i++) {
|
|
|
315 |
*dp = *(bp++) << 4;
|
|
|
316 |
*(dp++) |= *(bp++) & 0x0f;
|
|
|
317 |
}
|
|
|
318 |
if ( fwrite(data, sizeof(byte), mgr_line_size, pstream) < mgr_line_size )
|
|
|
319 |
return_error(gs_error_ioerror);
|
|
|
320 |
break;
|
|
|
321 |
|
|
|
322 |
case 8:
|
|
|
323 |
for (i = 0,bp = cur.data; i < mgr_line_size; i++, bp++)
|
|
|
324 |
*bp = backtable[*bp] + MGR_RESERVEDCOLORS;
|
|
|
325 |
if ( fwrite(cur.data, sizeof(cur.data[0]), mgr_line_size, pstream) < mgr_line_size )
|
|
|
326 |
return_error(gs_error_ioerror);
|
|
|
327 |
break;
|
|
|
328 |
}
|
|
|
329 |
}
|
|
|
330 |
gs_free(bdev->memory, (char *)data, mgr_line_size, 1, "cmgrN_print_page(done)");
|
|
|
331 |
|
|
|
332 |
if (bdev->mgr_depth == 4) {
|
|
|
333 |
for (i = 0; i < 16; i++) {
|
|
|
334 |
pc_4bit_map_color_rgb((gx_device *)0, (gx_color_index) i, prgb);
|
|
|
335 |
clut[i].colnum = i;
|
|
|
336 |
clut[i].red = clut2mgr(prgb[0], 16);
|
|
|
337 |
clut[i].green = clut2mgr(prgb[1], 16);
|
|
|
338 |
clut[i].blue = clut2mgr(prgb[2], 16);
|
|
|
339 |
}
|
|
|
340 |
}
|
|
|
341 |
if (bdev->mgr_depth == 8) {
|
|
|
342 |
for (i = 0; i < colors8; i++) {
|
|
|
343 |
mgr_8bit_map_color_rgb((gx_device *)0, (gx_color_index)
|
|
|
344 |
table[i], prgb);
|
|
|
345 |
clut[i].colnum = MGR_RESERVEDCOLORS + i;
|
|
|
346 |
clut[i].red = clut2mgr(prgb[0], 16);
|
|
|
347 |
clut[i].green = clut2mgr(prgb[1], 16);
|
|
|
348 |
clut[i].blue = clut2mgr(prgb[2], 16);
|
|
|
349 |
}
|
|
|
350 |
}
|
|
|
351 |
#if !arch_is_big_endian
|
|
|
352 |
swap_bwords( (unsigned char *) clut, sizeof( struct nclut ) * i );
|
|
|
353 |
#endif
|
|
|
354 |
if ( fwrite(&clut, sizeof(struct nclut), i, pstream) < i )
|
|
|
355 |
return_error(gs_error_ioerror);
|
|
|
356 |
return (code < 0 ? code : 0);
|
|
|
357 |
}
|
|
|
358 |
|
|
|
359 |
|
|
|
360 |
/* Color mapping routines for 8-bit color with a fixed palette */
|
|
|
361 |
/* (3 bits of R, 3 bits of G, 2 bits of B). */
|
|
|
362 |
/* We have to trade off even spacing of colors along each axis */
|
|
|
363 |
/* against the desire to have real gray shades; */
|
|
|
364 |
/* MGR compromises by using a 7x7x4 "cube" with extra gray shades */
|
|
|
365 |
/* (1/6, 1/2, and 5/6), instead of the obvious 8x8x4. */
|
|
|
366 |
|
|
|
367 |
gx_color_index
|
|
|
368 |
mgr_8bit_map_rgb_color(gx_device *dev, const gx_color_value cv[])
|
|
|
369 |
{
|
|
|
370 |
uint rv = cv[0] / (gx_max_color_value / 7 + 1);
|
|
|
371 |
uint gv = cv[1] / (gx_max_color_value / 7 + 1);
|
|
|
372 |
uint bv = cv[2] / (gx_max_color_value / 7 + 1);
|
|
|
373 |
return (gx_color_index)
|
|
|
374 |
(rv == gv && gv == bv ? rv + (256-7) :
|
|
|
375 |
(rv << 5) + (gv << 2) + (bv >> 1));
|
|
|
376 |
}
|
|
|
377 |
int
|
|
|
378 |
mgr_8bit_map_color_rgb(gx_device *dev, gx_color_index color,
|
|
|
379 |
gx_color_value prgb[3])
|
|
|
380 |
{ static const gx_color_value ramp[8] =
|
|
|
381 |
{ 0, gx_max_color_value / 6, gx_max_color_value / 3,
|
|
|
382 |
gx_max_color_value / 2, 2 * (gx_max_color_value / 3),
|
|
|
383 |
5 * (gx_max_color_value / 6), gx_max_color_value,
|
|
|
384 |
/* The 8th entry is not actually ever used, */
|
|
|
385 |
/* except to fill out the palette. */
|
|
|
386 |
gx_max_color_value
|
|
|
387 |
};
|
|
|
388 |
#define icolor (uint)color
|
|
|
389 |
if ( icolor >= 256-7 )
|
|
|
390 |
{ prgb[0] = prgb[1] = prgb[2] = ramp[icolor - (256-7)];
|
|
|
391 |
}
|
|
|
392 |
else
|
|
|
393 |
{ prgb[0] = ramp[(icolor >> 5) & 7];
|
|
|
394 |
prgb[1] = ramp[(icolor >> 2) & 7];
|
|
|
395 |
prgb[2] = ramp[(icolor & 3) << 1];
|
|
|
396 |
}
|
|
|
397 |
#undef icolor
|
|
|
398 |
return 0;
|
|
|
399 |
}
|
|
|
400 |
|
|
|
401 |
|
|
|
402 |
/* convert the 8-bit look-up table into the standard MGR look-up table */
|
|
|
403 |
private unsigned int
|
|
|
404 |
clut2mgr(
|
|
|
405 |
register int v, /* value in clut */
|
|
|
406 |
register int bits /* number of bits in clut */
|
|
|
407 |
)
|
|
|
408 |
{
|
|
|
409 |
register unsigned int i;
|
|
|
410 |
|
|
|
411 |
i = (unsigned int) 0xffffffff / ((1<<bits)-1);
|
|
|
412 |
return((v*i)/0x10000);
|
|
|
413 |
}
|
|
|
414 |
|
|
|
415 |
|
|
|
416 |
/*
|
|
|
417 |
* s w a p _ b w o r d s
|
|
|
418 |
*/
|
|
|
419 |
private void
|
|
|
420 |
swap_bwords(register unsigned char *p, int n)
|
|
|
421 |
{
|
|
|
422 |
register unsigned char c;
|
|
|
423 |
|
|
|
424 |
n /= 2;
|
|
|
425 |
|
|
|
426 |
for (; n > 0; n--, p += 2) {
|
|
|
427 |
c = p[0];
|
|
|
428 |
p[0] = p[1];
|
|
|
429 |
p[1] = c;
|
|
|
430 |
}
|
|
|
431 |
}
|