~paulliu/ubuntu/quantal/freerdp/fixext

« back to all changes in this revision

Viewing changes to X11/xf_color.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2012-01-31 10:02:14 UTC
  • mto: This revision was merged to the branch mainline in revision 11.
  • Revision ID: package-import@ubuntu.com-20120131100214-zvig71djj2sqgq22
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
   Copyright (c) 2009-2010 Jay Sorg
3
 
 
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:
10
 
 
11
 
   The above copyright notice and this permission notice shall be included
12
 
   in all copies or substantial portions of the Software.
13
 
 
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.
21
 
*/
22
 
 
23
 
/*
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
28
 
    24 -> 32  24 -> 24
29
 
    32 -> 32
30
 
*/
31
 
 
32
 
#include <X11/Xlib.h>
33
 
#include <X11/Xutil.h>
34
 
#include <stdio.h>
35
 
#include <stdlib.h>
36
 
#include <string.h>
37
 
#include "xf_types.h"
38
 
 
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;
44
 
 
45
 
#define SPLIT24BGR(_red, _green, _blue, _pixel) \
46
 
  _red = _pixel & 0xff; \
47
 
  _green = (_pixel & 0xff00) >> 8; \
48
 
  _blue = (_pixel & 0xff0000) >> 16;
49
 
 
50
 
#define SPLIT24RGB(_red, _green, _blue, _pixel) \
51
 
  _blue  = _pixel & 0xff; \
52
 
  _green = (_pixel & 0xff00) >> 8; \
53
 
  _red   = (_pixel & 0xff0000) >> 16;
54
 
 
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);
59
 
 
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);
64
 
 
65
 
#define MAKE32RGB(_alpha, _red, _green, _blue) \
66
 
  (_alpha << 24) | (_red << 16) | (_green << 8) | _blue;
67
 
 
68
 
#define MAKE24RGB(_red, _green, _blue) \
69
 
  (_red << 16) | (_green << 8) | _blue;
70
 
 
71
 
#define MAKE15RGB(_red, _green, _blue) \
72
 
  (((_red & 0xff) >> 3) << 10) | \
73
 
  (((_green & 0xff) >> 3) <<  5) | \
74
 
  (((_blue & 0xff) >> 3) <<  0)
75
 
 
76
 
#define MAKE16RGB(_red, _green, _blue) \
77
 
  (((_red & 0xff) >> 3) << 11) | \
78
 
  (((_green & 0xff) >> 2) <<  5) | \
79
 
  (((_blue & 0xff) >> 3) <<  0)
80
 
 
81
 
static int
82
 
get_pixel(uint8 * data, int x, int y, int width, int height, int bpp)
83
 
{
84
 
        int start;
85
 
        int shift;
86
 
        int red;
87
 
        int green;
88
 
        int blue;
89
 
        uint16 * s16;
90
 
        uint32 * s32;
91
 
 
92
 
        switch (bpp)
93
 
        {
94
 
                case  1:
95
 
                        width = (width + 7) / 8;
96
 
                        start = (y * width) + x / 8;
97
 
                        shift = x % 8;
98
 
                        return (data[start] & (0x80 >> shift)) != 0;
99
 
                case 8:
100
 
                        return data[y * width + x];
101
 
                case 15:
102
 
                case 16:
103
 
                        s16 = (uint16 *) data;
104
 
                        return s16[y * width + x];
105
 
                case 24:
106
 
                        data += y * width * 3;
107
 
                        data += x * 3;
108
 
                        red = data[0];
109
 
                        green = data[1];
110
 
                        blue = data[2];
111
 
                        return MAKE24RGB(red, green, blue);
112
 
                case 32:
113
 
                        s32 = (uint32 *) data;
114
 
                        return s32[y * width + x];
115
 
                default:
116
 
                        printf("unknonw in get_pixel\n");
117
 
                        break;
118
 
        }
119
 
        return 0;
120
 
}
121
 
 
122
 
static void
123
 
set_pixel(uint8 * data, int x, int y, int width, int height, int bpp, int pixel)
124
 
{
125
 
        int start;
126
 
        int shift;
127
 
        int * d32;
128
 
 
129
 
        if (bpp == 1)
130
 
        {
131
 
                width = (width + 7) / 8;
132
 
                start = (y * width) + x / 8;
133
 
                shift = x % 8;
134
 
                if (pixel)
135
 
                {
136
 
                        data[start] = data[start] | (0x80 >> shift);
137
 
                }
138
 
                else
139
 
                {
140
 
                        data[start] = data[start] & ~(0x80 >> shift);
141
 
                }
142
 
        }
143
 
        else if (bpp == 32)
144
 
        {
145
 
                d32 = (int *) data;
146
 
                d32[y * width + x] = pixel;
147
 
        }
148
 
        else
149
 
        {
150
 
                printf("unknonw in set_pixel\n");
151
 
        }
152
 
}
153
 
 
154
 
static int
155
 
xf_color(xfInfo * xfi, int in_color, int in_bpp, int out_bpp)
156
 
{
157
 
        int alpha;
158
 
        int red;
159
 
        int green;
160
 
        int blue;
161
 
        int rv;
162
 
 
163
 
        alpha = 0xff;
164
 
        red = 0;
165
 
        green = 0;
166
 
        blue = 0;
167
 
        rv = 0;
168
 
        switch (in_bpp)
169
 
        {
170
 
                case 32:
171
 
                        SPLIT32BGR(alpha, red, green, blue, in_color);
172
 
                        break;
173
 
                case 24:
174
 
                        SPLIT24BGR(red, green, blue, in_color);
175
 
                        break;
176
 
                case 16:
177
 
                        SPLIT16RGB(red, green, blue, in_color);
178
 
                        break;
179
 
                case 15:
180
 
                        SPLIT15RGB(red, green, blue, in_color);
181
 
                        break;
182
 
                case 8:
183
 
                        in_color &= 0xff;
184
 
                        SPLIT24RGB(red, green, blue, xfi->colormap[in_color]);
185
 
                        break;
186
 
                case 1:
187
 
                        if (in_color != 0)
188
 
                        {
189
 
                                red = 0xff;
190
 
                                green = 0xff;
191
 
                                blue = 0xff;
192
 
                        }
193
 
                        break;
194
 
                default:
195
 
                        printf("xf_color: bad in_bpp %d\n", in_bpp);
196
 
                        break;
197
 
        }
198
 
        switch (out_bpp)
199
 
        {
200
 
                case 32:
201
 
                        rv = MAKE32RGB(alpha, red, green, blue);
202
 
                        break;
203
 
                case 24:
204
 
                        rv = MAKE24RGB(red, green, blue);
205
 
                        break;
206
 
                case 16:
207
 
                        rv = MAKE16RGB(red, green, blue);
208
 
                        break;
209
 
                case 15:
210
 
                        rv = MAKE15RGB(red, green, blue);
211
 
                        break;
212
 
                case 1:
213
 
                        if ((red != 0) || (green != 0) || (blue != 0))
214
 
                        {
215
 
                                rv = 1;
216
 
                        }
217
 
                        break;
218
 
                default:
219
 
                        printf("xf_color: bad out_bpp %d\n", out_bpp);
220
 
                        break;
221
 
        }
222
 
        return rv;
223
 
}
224
 
 
225
 
int
226
 
xf_color_convert(xfInfo * xfi, rdpSet * settings, int color)
227
 
{
228
 
        return xf_color(xfi, color, settings->server_depth, xfi->bpp);
229
 
}
230
 
 
231
 
uint8 *
232
 
xf_image_convert(xfInfo * xfi, rdpSet * settings, int width, int height,
233
 
        uint8 * in_data)
234
 
{
235
 
        int red;
236
 
        int green;
237
 
        int blue;
238
 
        int index;
239
 
        int pixel;
240
 
        uint8 * out_data;
241
 
        uint8 * src8;
242
 
        uint8 * dst8;
243
 
 
244
 
        if ((settings->server_depth == 24) && (xfi->bpp == 32))
245
 
        {
246
 
                out_data = (uint8 *) malloc(width * height * 4);
247
 
                src8 = in_data;
248
 
                dst8 = out_data;
249
 
                for (index = width * height; index > 0; index--)
250
 
                {
251
 
                        blue = *(src8++);
252
 
                        green = *(src8++);
253
 
                        red = *(src8++);
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;
259
 
                }
260
 
                return out_data;
261
 
        }
262
 
        else if ((settings->server_depth == 16) && (xfi->bpp == 32))
263
 
        {
264
 
                out_data = (uint8 *) malloc(width * height * 4);
265
 
                src8 = in_data;
266
 
                dst8 = out_data;
267
 
                for (index = width * height; index > 0; index--)
268
 
                {
269
 
                        pixel = *src8++;
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;
277
 
                }
278
 
                return out_data;
279
 
        }
280
 
        else if ((settings->server_depth == 15) && (xfi->bpp == 32))
281
 
        {
282
 
                out_data = (uint8 *) malloc(width * height * 4);
283
 
                src8 = in_data;
284
 
                dst8 = out_data;
285
 
                for (index = width * height; index > 0; index--)
286
 
                {
287
 
                        pixel = *src8++;
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;
295
 
                }
296
 
                return out_data;
297
 
        }
298
 
        else if ((settings->server_depth == 8) && (xfi->bpp == 32))
299
 
        {
300
 
                out_data = (uint8 *) malloc(width * height * 4);
301
 
                src8 = in_data;
302
 
                dst8 = out_data;
303
 
                for (index = width * height; index > 0; index--)
304
 
                {
305
 
                        pixel = *src8;
306
 
                        src8++;
307
 
                        pixel = xfi->colormap[pixel];
308
 
                        *dst8++ = pixel & 0xff;
309
 
                        *dst8++ = (pixel >> 8) & 0xff;
310
 
                        *dst8++ = (pixel >> 16) & 0xff;
311
 
                        *dst8++ = (pixel >> 24) & 0xff;
312
 
                }
313
 
                return out_data;
314
 
        }
315
 
        else if ((settings->server_depth == 15) && (xfi->bpp == 16))
316
 
        {
317
 
                out_data = (uint8 *) malloc(width * height * 2);
318
 
                src8 = in_data;
319
 
                dst8 = out_data;
320
 
                for (index = width * height; index > 0; index--)
321
 
                {
322
 
                        pixel = *src8++;
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;
328
 
                }
329
 
                return out_data;
330
 
        }
331
 
        else if ((settings->server_depth == 8) && (xfi->bpp == 16))
332
 
        {
333
 
                out_data = (uint8 *) malloc(width * height * 2);
334
 
                src8 = in_data;
335
 
                dst8 = out_data;
336
 
                for (index = width * height; index > 0; index--)
337
 
                {
338
 
                        pixel = *src8;
339
 
                        src8++;
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;
345
 
                }
346
 
                return out_data;
347
 
        }
348
 
        else if ((settings->server_depth == 8) && (xfi->bpp == 15))
349
 
        {
350
 
                out_data = (uint8 *) malloc(width * height * 2);
351
 
                src8 = in_data;
352
 
                dst8 = out_data;
353
 
                for (index = width * height; index > 0; index--)
354
 
                {
355
 
                        pixel = *src8;
356
 
                        src8++;
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;
362
 
                }
363
 
                return out_data;
364
 
        }
365
 
        return in_data;
366
 
}
367
 
 
368
 
RD_HPALETTE
369
 
xf_create_colormap(xfInfo * xfi, rdpSet * settings, RD_PALETTE * colors)
370
 
{
371
 
        int * colormap;
372
 
        int index;
373
 
        int red;
374
 
        int green;
375
 
        int blue;
376
 
        int count;
377
 
 
378
 
        colormap = (int *) malloc(sizeof(int) * 256);
379
 
        memset(colormap, 0, sizeof(int) * 256);
380
 
        count = colors->ncolors;
381
 
        if (count > 256)
382
 
        {
383
 
                count = 256;
384
 
        }
385
 
        for (index = count - 1; index >= 0; index--)
386
 
        {
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);
391
 
        }
392
 
        return (RD_HPALETTE) colormap;
393
 
}
394
 
 
395
 
int
396
 
xf_set_colormap(xfInfo * xfi, rdpSet * settings, RD_HPALETTE map)
397
 
{
398
 
        if (xfi->colormap != NULL)
399
 
        {
400
 
                free(xfi->colormap);
401
 
        }
402
 
        xfi->colormap = (int *) map;
403
 
        return 0;
404
 
}
405
 
 
406
 
/* create mono cursor */
407
 
int
408
 
xf_cursor_convert_mono(xfInfo * xfi, uint8 * src_data, uint8 * msk_data,
409
 
        uint8 * xormask, uint8 * andmask, int width, int height, int bpp)
410
 
{
411
 
        int i;
412
 
        int j;
413
 
        int jj;
414
 
        int xpixel;
415
 
        int apixel;
416
 
 
417
 
        for (j = 0; j < height; j++)
418
 
        {
419
 
                jj = (bpp == 1) ? j : (height - 1) - j;
420
 
                for (i = 0; i < width; i++)
421
 
                {
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))
426
 
                        {
427
 
                                /* use pattern(not solid black) for xor area */
428
 
                                xpixel = (i & 1) == (j & 1);
429
 
                                apixel = 1;
430
 
                        }
431
 
                        else
432
 
                        {
433
 
                                xpixel = xpixel != 0;
434
 
                                apixel = apixel == 0;
435
 
                        }
436
 
                        set_pixel(src_data, i, j, width, height, 1, xpixel);
437
 
                        set_pixel(msk_data, i, j, width, height, 1, apixel);
438
 
                }
439
 
        }
440
 
        return 0;
441
 
}
442
 
 
443
 
/* create 32 bpp cursor */
444
 
int
445
 
xf_cursor_convert_alpha(xfInfo * xfi, uint8 * alpha_data,
446
 
        uint8 * xormask, uint8 * andmask, int width, int height, int bpp)
447
 
{
448
 
        int i;
449
 
        int j;
450
 
        int jj;
451
 
        int xpixel;
452
 
        int apixel;
453
 
 
454
 
        for (j = 0; j < height; j++)
455
 
        {
456
 
                jj = (bpp == 1) ? j : (height - 1) - j;
457
 
                for (i = 0; i < width; i++)
458
 
                {
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);
462
 
                        if (apixel != 0)
463
 
                        {
464
 
                                if ((xpixel & 0xffffff) == 0xffffff)
465
 
                                {
466
 
                                        /* use pattern(not solid black) for xor area */
467
 
                                        xpixel = (i & 1) == (j & 1);
468
 
                                        xpixel = xpixel ? 0xffffff : 0;
469
 
                                        xpixel |= 0xff000000;
470
 
                                }
471
 
                                else if (xpixel == 0xff000000)
472
 
                                {
473
 
                                        xpixel = 0;
474
 
                                }
475
 
                        }
476
 
                        set_pixel(alpha_data, i, j, width, height, 32, xpixel);
477
 
                }
478
 
        }
479
 
        return 0;
480
 
}