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