blob: 348f12b9c18a42714bb16e92e8c0478afcdbf575 [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18//
19// transInitTempl.h - templates for functions to initialise lookup tables for
20// the translation functions.
21//
22// This file is #included after having set the following macros:
23// BPPOUT - 8, 16 or 32
24
25#if !defined(BPPOUT)
26#error "transInitTempl.h: BPPOUT not defined"
27#endif
28
29namespace rfb {
30
31// CONCAT2E concatenates its arguments, expanding them if they are macros
32
33#ifndef CONCAT2E
34#define CONCAT2(a,b) a##b
35#define CONCAT2E(a,b) CONCAT2(a,b)
36#endif
37
38#ifndef SWAP16
39#define SWAP16(n) ((((n) & 0xff) << 8) | (((n) >> 8) & 0xff))
40#endif
41
42#ifndef SWAP32
43#define SWAP32(n) (((n) >> 24) | (((n) & 0x00ff0000) >> 8) | \
44 (((n) & 0x0000ff00) << 8) | ((n) << 24))
45#endif
46
47#define OUTPIXEL rdr::CONCAT2E(U,BPPOUT)
48#define SWAPOUT CONCAT2E(SWAP,BPPOUT)
Pierre Ossmanb6b4dc62014-01-20 15:05:21 +010049#define initSimpleOUT CONCAT2E(initSimple,BPPOUT)
50#define initRGBOUT CONCAT2E(initRGB,BPPOUT)
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000051#define initOneRGBTableOUT CONCAT2E(initOneRGBTable,BPPOUT)
52#define initOneRGBCubeTableOUT CONCAT2E(initOneRGBCubeTable,BPPOUT)
53
54#ifndef TRANS_INIT_TEMPL_ENDIAN_TEST
55#define TRANS_INIT_TEMPL_ENDIAN_TEST
56 static rdr::U32 endianTest = 1;
57 static bool nativeBigEndian = *(rdr::U8*)(&endianTest) != 1;
58#endif
59
Pierre Ossmanb6b4dc62014-01-20 15:05:21 +010060void initSimpleOUT (rdr::U8** tablep, const PixelFormat& inPF,
61 const PixelFormat& outPF)
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000062{
63 if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
64 throw Exception("Internal error: inPF is not native endian");
65
66 int size = 1 << inPF.bpp;
67
68 delete [] *tablep;
69 *tablep = new rdr::U8[size * sizeof(OUTPIXEL)];
70 OUTPIXEL* table = (OUTPIXEL*)*tablep;
71
72 for (int i = 0; i < size; i++) {
73 int r = (i >> inPF.redShift) & inPF.redMax;
74 int g = (i >> inPF.greenShift) & inPF.greenMax;
75 int b = (i >> inPF.blueShift) & inPF.blueMax;
76
77 r = (r * outPF.redMax + inPF.redMax/2) / inPF.redMax;
78 g = (g * outPF.greenMax + inPF.greenMax/2) / inPF.greenMax;
79 b = (b * outPF.blueMax + inPF.blueMax/2) / inPF.blueMax;
80
81 table[i] = ((r << outPF.redShift) |
82 (g << outPF.greenShift) |
83 (b << outPF.blueShift));
84#if (BPPOUT != 8)
85 if (outPF.bigEndian != nativeBigEndian)
86 table[i] = SWAPOUT (table[i]);
87#endif
88 }
89}
90
Pierre Ossmanb6b4dc62014-01-20 15:05:21 +010091static void initOneRGBTableOUT (OUTPIXEL* table, int inMax, int outMax,
92 int outShift, bool swap)
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000093{
94 int size = inMax + 1;
95
96 for (int i = 0; i < size; i++) {
97 table[i] = ((i * outMax + inMax / 2) / inMax) << outShift;
98#if (BPPOUT != 8)
99 if (swap)
100 table[i] = SWAPOUT (table[i]);
101#endif
102 }
103}
104
Pierre Ossmanb6b4dc62014-01-20 15:05:21 +0100105void initRGBOUT (rdr::U8** tablep, const PixelFormat& inPF,
106 const PixelFormat& outPF)
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000107{
108 if (inPF.bpp != 8 && inPF.bigEndian != nativeBigEndian)
109 throw Exception("Internal error: inPF is not native endian");
110
111 int size = inPF.redMax + inPF.greenMax + inPF.blueMax + 3;
112
113 delete [] *tablep;
114 *tablep = new rdr::U8[size * sizeof(OUTPIXEL)];
115
116 OUTPIXEL* redTable = (OUTPIXEL*)*tablep;
117 OUTPIXEL* greenTable = redTable + inPF.redMax + 1;
118 OUTPIXEL* blueTable = greenTable + inPF.greenMax + 1;
119
120 bool swap = (outPF.bigEndian != nativeBigEndian);
121
122 initOneRGBTableOUT (redTable, inPF.redMax, outPF.redMax,
123 outPF.redShift, swap);
124 initOneRGBTableOUT (greenTable, inPF.greenMax, outPF.greenMax,
125 outPF.greenShift, swap);
126 initOneRGBTableOUT (blueTable, inPF.blueMax, outPF.blueMax,
127 outPF.blueShift, swap);
128}
129
130
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000131#undef OUTPIXEL
Pierre Ossmanb6b4dc62014-01-20 15:05:21 +0100132#undef initSimpleOUT
133#undef initRGBOUT
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000134#undef initOneRGBTableOUT
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000135}