2
Copyright (c) 2009-2010 Jay Sorg
4
Permission is hereby granted, free of charge, to any person obtaining a
5
copy of this software and associated documentation files (the "Software"),
6
to deal in the Software without restriction, including without limitation
7
the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
and/or sell copies of the Software, and to permit persons to whom the
9
Software is furnished to do so, subject to the following conditions:
11
The above copyright notice and this permission notice shall be included
12
in all copies or substantial portions of the Software.
14
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20
DEALINGS IN THE SOFTWARE.
24
Valid color conversions
25
8 -> 32 8 -> 24 8 -> 16 8 -> 15
26
15 -> 32 15 -> 24 15 -> 16 15 -> 15
27
16 -> 32 16 -> 24 16 -> 16
33
#include <X11/Xutil.h>
39
#define SPLIT32BGR(_alpha, _red, _green, _blue, _pixel) \
40
_red = _pixel & 0xff; \
41
_green = (_pixel & 0xff00) >> 8; \
42
_blue = (_pixel & 0xff0000) >> 16; \
43
_alpha = (_pixel & 0xff000000) >> 24;
45
#define SPLIT24BGR(_red, _green, _blue, _pixel) \
46
_red = _pixel & 0xff; \
47
_green = (_pixel & 0xff00) >> 8; \
48
_blue = (_pixel & 0xff0000) >> 16;
50
#define SPLIT24RGB(_red, _green, _blue, _pixel) \
51
_blue = _pixel & 0xff; \
52
_green = (_pixel & 0xff00) >> 8; \
53
_red = (_pixel & 0xff0000) >> 16;
55
#define SPLIT16RGB(_red, _green, _blue, _pixel) \
56
_red = ((_pixel >> 8) & 0xf8) | ((_pixel >> 13) & 0x7); \
57
_green = ((_pixel >> 3) & 0xfc) | ((_pixel >> 9) & 0x3); \
58
_blue = ((_pixel << 3) & 0xf8) | ((_pixel >> 2) & 0x7);
60
#define SPLIT15RGB(_red, _green, _blue, _pixel) \
61
_red = ((_pixel >> 7) & 0xf8) | ((_pixel >> 12) & 0x7); \
62
_green = ((_pixel >> 2) & 0xf8) | ((_pixel >> 8) & 0x7); \
63
_blue = ((_pixel << 3) & 0xf8) | ((_pixel >> 2) & 0x7);
65
#define MAKE32RGB(_alpha, _red, _green, _blue) \
66
(_alpha << 24) | (_red << 16) | (_green << 8) | _blue;
68
#define MAKE24RGB(_red, _green, _blue) \
69
(_red << 16) | (_green << 8) | _blue;
71
#define MAKE15RGB(_red, _green, _blue) \
72
(((_red & 0xff) >> 3) << 10) | \
73
(((_green & 0xff) >> 3) << 5) | \
74
(((_blue & 0xff) >> 3) << 0)
76
#define MAKE16RGB(_red, _green, _blue) \
77
(((_red & 0xff) >> 3) << 11) | \
78
(((_green & 0xff) >> 2) << 5) | \
79
(((_blue & 0xff) >> 3) << 0)
82
get_pixel(uint8 * data, int x, int y, int width, int height, int bpp)
95
width = (width + 7) / 8;
96
start = (y * width) + x / 8;
98
return (data[start] & (0x80 >> shift)) != 0;
100
return data[y * width + x];
103
s16 = (uint16 *) data;
104
return s16[y * width + x];
106
data += y * width * 3;
111
return MAKE24RGB(red, green, blue);
113
s32 = (uint32 *) data;
114
return s32[y * width + x];
116
printf("unknonw in get_pixel\n");
123
set_pixel(uint8 * data, int x, int y, int width, int height, int bpp, int pixel)
131
width = (width + 7) / 8;
132
start = (y * width) + x / 8;
136
data[start] = data[start] | (0x80 >> shift);
140
data[start] = data[start] & ~(0x80 >> shift);
146
d32[y * width + x] = pixel;
150
printf("unknonw in set_pixel\n");
155
xf_color(xfInfo * xfi, int in_color, int in_bpp, int out_bpp)
171
SPLIT32BGR(alpha, red, green, blue, in_color);
174
SPLIT24BGR(red, green, blue, in_color);
177
SPLIT16RGB(red, green, blue, in_color);
180
SPLIT15RGB(red, green, blue, in_color);
184
SPLIT24RGB(red, green, blue, xfi->colormap[in_color]);
195
printf("xf_color: bad in_bpp %d\n", in_bpp);
201
rv = MAKE32RGB(alpha, red, green, blue);
204
rv = MAKE24RGB(red, green, blue);
207
rv = MAKE16RGB(red, green, blue);
210
rv = MAKE15RGB(red, green, blue);
213
if ((red != 0) || (green != 0) || (blue != 0))
219
printf("xf_color: bad out_bpp %d\n", out_bpp);
226
xf_color_convert(xfInfo * xfi, rdpSet * settings, int color)
228
return xf_color(xfi, color, settings->server_depth, xfi->bpp);
232
xf_image_convert(xfInfo * xfi, rdpSet * settings, int width, int height,
244
if ((settings->server_depth == 24) && (xfi->bpp == 32))
246
out_data = (uint8 *) malloc(width * height * 4);
249
for (index = width * height; index > 0; index--)
254
pixel = MAKE24RGB(red, green, blue);
255
*dst8++ = pixel & 0xff;
256
*dst8++ = (pixel >> 8) & 0xff;
257
*dst8++ = (pixel >> 16) & 0xff;
258
*dst8++ = (pixel >> 24) & 0xff;
262
else if ((settings->server_depth == 16) && (xfi->bpp == 32))
264
out_data = (uint8 *) malloc(width * height * 4);
267
for (index = width * height; index > 0; index--)
270
pixel |= (*src8++) << 8;
271
SPLIT16RGB(red, green, blue, pixel);
272
pixel = MAKE24RGB(red, green, blue);
273
*dst8++ = pixel & 0xff;
274
*dst8++ = (pixel >> 8) & 0xff;
275
*dst8++ = (pixel >> 16) & 0xff;
276
*dst8++ = (pixel >> 24) & 0xff;
280
else if ((settings->server_depth == 15) && (xfi->bpp == 32))
282
out_data = (uint8 *) malloc(width * height * 4);
285
for (index = width * height; index > 0; index--)
288
pixel |= (*src8++) << 8;
289
SPLIT15RGB(red, green, blue, pixel);
290
pixel = MAKE24RGB(red, green, blue);
291
*dst8++ = pixel & 0xff;
292
*dst8++ = (pixel >> 8) & 0xff;
293
*dst8++ = (pixel >> 16) & 0xff;
294
*dst8++ = (pixel >> 24) & 0xff;
298
else if ((settings->server_depth == 8) && (xfi->bpp == 32))
300
out_data = (uint8 *) malloc(width * height * 4);
303
for (index = width * height; index > 0; index--)
307
pixel = xfi->colormap[pixel];
308
*dst8++ = pixel & 0xff;
309
*dst8++ = (pixel >> 8) & 0xff;
310
*dst8++ = (pixel >> 16) & 0xff;
311
*dst8++ = (pixel >> 24) & 0xff;
315
else if ((settings->server_depth == 15) && (xfi->bpp == 16))
317
out_data = (uint8 *) malloc(width * height * 2);
320
for (index = width * height; index > 0; index--)
323
pixel |= (*src8++) << 8;
324
SPLIT15RGB(red, green, blue, pixel);
325
pixel = MAKE16RGB(red, green, blue);
326
*dst8++ = pixel & 0xff;
327
*dst8++ = (pixel >> 8) & 0xff;
331
else if ((settings->server_depth == 8) && (xfi->bpp == 16))
333
out_data = (uint8 *) malloc(width * height * 2);
336
for (index = width * height; index > 0; index--)
340
pixel = xfi->colormap[pixel];
341
SPLIT24RGB(red, green, blue, pixel);
342
pixel = MAKE16RGB(red, green, blue);
343
*dst8++ = pixel & 0xff;
344
*dst8++ = (pixel >> 8) & 0xff;
348
else if ((settings->server_depth == 8) && (xfi->bpp == 15))
350
out_data = (uint8 *) malloc(width * height * 2);
353
for (index = width * height; index > 0; index--)
357
pixel = xfi->colormap[pixel];
358
SPLIT24RGB(red, green, blue, pixel);
359
pixel = MAKE15RGB(red, green, blue);
360
*dst8++ = pixel & 0xff;
361
*dst8++ = (pixel >> 8) & 0xff;
369
xf_create_colormap(xfInfo * xfi, rdpSet * settings, RD_PALETTE * colors)
378
colormap = (int *) malloc(sizeof(int) * 256);
379
memset(colormap, 0, sizeof(int) * 256);
380
count = colors->ncolors;
385
for (index = count - 1; index >= 0; index--)
387
red = colors->colors[index].red;
388
green = colors->colors[index].green;
389
blue = colors->colors[index].blue;
390
colormap[index] = MAKE24RGB(red, green, blue);
392
return (RD_HPALETTE) colormap;
396
xf_set_colormap(xfInfo * xfi, rdpSet * settings, RD_HPALETTE map)
398
if (xfi->colormap != NULL)
402
xfi->colormap = (int *) map;
406
/* create mono cursor */
408
xf_cursor_convert_mono(xfInfo * xfi, uint8 * src_data, uint8 * msk_data,
409
uint8 * xormask, uint8 * andmask, int width, int height, int bpp)
417
for (j = 0; j < height; j++)
419
jj = (bpp == 1) ? j : (height - 1) - j;
420
for (i = 0; i < width; i++)
422
xpixel = get_pixel(xormask, i, jj, width, height, bpp);
423
xpixel = xf_color(xfi, xpixel, bpp, 24);
424
apixel = get_pixel(andmask, i, jj, width, height, 1);
425
if ((xpixel == 0xffffff) && (apixel != 0))
427
/* use pattern(not solid black) for xor area */
428
xpixel = (i & 1) == (j & 1);
433
xpixel = xpixel != 0;
434
apixel = apixel == 0;
436
set_pixel(src_data, i, j, width, height, 1, xpixel);
437
set_pixel(msk_data, i, j, width, height, 1, apixel);
443
/* create 32 bpp cursor */
445
xf_cursor_convert_alpha(xfInfo * xfi, uint8 * alpha_data,
446
uint8 * xormask, uint8 * andmask, int width, int height, int bpp)
454
for (j = 0; j < height; j++)
456
jj = (bpp == 1) ? j : (height - 1) - j;
457
for (i = 0; i < width; i++)
459
xpixel = get_pixel(xormask, i, jj, width, height, bpp);
460
xpixel = xf_color(xfi, xpixel, bpp, 32);
461
apixel = get_pixel(andmask, i, jj, width, height, 1);
464
if ((xpixel & 0xffffff) == 0xffffff)
466
/* use pattern(not solid black) for xor area */
467
xpixel = (i & 1) == (j & 1);
468
xpixel = xpixel ? 0xffffff : 0;
469
xpixel |= 0xff000000;
471
else if (xpixel == 0xff000000)
476
set_pixel(alpha_data, i, j, width, height, 32, xpixel);