1/*
2 *  OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
3 *  Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
4 *  All Rights Reserved.
5 *
6 *  This is free software; you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation; either version 2 of the License, or
9 *  (at your option) any later version.
10 *
11 *  This software is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with this software; if not, write to the Free Software
18 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
19 *  USA.
20 */
21
22static void
23rfbInitOneRGBTable24 (uint8_t *table, int inMax, int outMax, int outShift,int swap);
24
25
26static void
27rfbInitColourMapSingleTable24(char **table, rfbPixelFormat *in,
28                            rfbPixelFormat *out,rfbColourMap* colourMap)
29{
30    uint32_t i, r, g, b, outValue;
31    uint8_t *t;
32    uint8_t c;
33    unsigned int nEntries = 1 << in->bitsPerPixel;
34    int shift = colourMap->is16?16:8;
35
36    if (*table) free(*table);
37    *table = (char *)malloc(nEntries * 3 + 1);
38    t = (uint8_t *)*table;
39
40    for (i = 0; i < nEntries; i++) {
41        r = g = b = 0;
42	if(i < colourMap->count) {
43	  if(colourMap->is16) {
44	    r = colourMap->data.shorts[3*i+0];
45	    g = colourMap->data.shorts[3*i+1];
46	    b = colourMap->data.shorts[3*i+2];
47	  } else {
48	    r = colourMap->data.bytes[3*i+0];
49	    g = colourMap->data.bytes[3*i+1];
50	    b = colourMap->data.bytes[3*i+2];
51	  }
52	}
53        outValue = ((((r * (1 + out->redMax)) >> shift) << out->redShift) |
54                (((g * (1 + out->greenMax)) >> shift) << out->greenShift) |
55                (((b * (1 + out->blueMax)) >> shift) << out->blueShift));
56	*(uint32_t*)&t[3*i] = outValue;
57	if(!rfbEndianTest)
58	  memmove(t+3*i,t+3*i+1,3);
59        if (out->bigEndian != in->bigEndian) {
60	  c = t[3*i]; t[3*i] = t[3*i+2]; t[3*i+2] = c;
61        }
62    }
63}
64
65/*
66 * rfbInitTrueColourSingleTable sets up a single lookup table for truecolour
67 * translation.
68 */
69
70static void
71rfbInitTrueColourSingleTable24 (char **table, rfbPixelFormat *in,
72                                 rfbPixelFormat *out)
73{
74    int i,outValue;
75    int inRed, inGreen, inBlue, outRed, outGreen, outBlue;
76    uint8_t *t;
77    uint8_t c;
78    int nEntries = 1 << in->bitsPerPixel;
79
80    if (*table) free(*table);
81    *table = (char *)malloc(nEntries * 3 + 1);
82    t = (uint8_t *)*table;
83
84    for (i = 0; i < nEntries; i++) {
85        inRed   = (i >> in->redShift)   & in->redMax;
86        inGreen = (i >> in->greenShift) & in->greenMax;
87        inBlue  = (i >> in->blueShift)  & in->blueMax;
88
89        outRed   = (inRed   * out->redMax   + in->redMax / 2)   / in->redMax;
90        outGreen = (inGreen * out->greenMax + in->greenMax / 2) / in->greenMax;
91        outBlue  = (inBlue  * out->blueMax  + in->blueMax / 2)  / in->blueMax;
92
93	outValue = ((outRed   << out->redShift)   |
94                (outGreen << out->greenShift) |
95                (outBlue  << out->blueShift));
96	*(uint32_t*)&t[3*i] = outValue;
97	if(!rfbEndianTest)
98	  memmove(t+3*i,t+3*i+1,3);
99        if (out->bigEndian != in->bigEndian) {
100	  c = t[3*i]; t[3*i] = t[3*i+2]; t[3*i+2] = c;
101        }
102    }
103}
104
105
106/*
107 * rfbInitTrueColourRGBTables sets up three separate lookup tables for the
108 * red, green and blue values.
109 */
110
111static void
112rfbInitTrueColourRGBTables24 (char **table, rfbPixelFormat *in,
113                               rfbPixelFormat *out)
114{
115    uint8_t *redTable;
116    uint8_t *greenTable;
117    uint8_t *blueTable;
118
119    if (*table) free(*table);
120    *table = (char *)malloc((in->redMax + in->greenMax + in->blueMax + 3)
121                            * 3 + 1);
122    redTable = (uint8_t *)*table;
123    greenTable = redTable + 3*(in->redMax + 1);
124    blueTable = greenTable + 3*(in->greenMax + 1);
125
126    rfbInitOneRGBTable24 (redTable, in->redMax, out->redMax,
127                           out->redShift, (out->bigEndian != in->bigEndian));
128    rfbInitOneRGBTable24 (greenTable, in->greenMax, out->greenMax,
129                           out->greenShift, (out->bigEndian != in->bigEndian));
130    rfbInitOneRGBTable24 (blueTable, in->blueMax, out->blueMax,
131                           out->blueShift, (out->bigEndian != in->bigEndian));
132}
133
134static void
135rfbInitOneRGBTable24 (uint8_t *table, int inMax, int outMax, int outShift,
136                       int swap)
137{
138    int i;
139    int nEntries = inMax + 1;
140    uint32_t outValue;
141    uint8_t c;
142
143    for (i = 0; i < nEntries; i++) {
144      outValue = ((i * outMax + inMax / 2) / inMax) << outShift;
145      *(uint32_t *)&table[3*i] = outValue;
146      if(!rfbEndianTest)
147	memmove(table+3*i,table+3*i+1,3);
148        if (swap) {
149	  c = table[3*i]; table[3*i] = table[3*i+2];
150	  table[3*i+2] = c;
151        }
152    }
153}
154