blob: 09dc7f959c3d54383ec7599fe03ea03553febaa9 [file] [log] [blame]
Constantin Kaplinskyde179d42006-04-16 06:53:44 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 *
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00003 * 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// transTempl.h - templates for translation functions.
20//
21// This file is #included after having set the following macros:
22// BPPIN - 8, 16 or 32
23// BPPOUT - 8, 16 or 32
24
25#if !defined(BPPIN) || !defined(BPPOUT)
26#error "transTempl.h: BPPIN or BPPOUT not defined"
27#endif
28
29// CONCAT2E concatenates its arguments, expanding them if they are macros
30
31#ifndef CONCAT2E
32#define CONCAT2(a,b) a##b
33#define CONCAT2E(a,b) CONCAT2(a,b)
34#endif
35
36#ifndef CONCAT4E
37#define CONCAT4(a,b,c,d) a##b##c##d
38#define CONCAT4E(a,b,c,d) CONCAT4(a,b,c,d)
39#endif
40
41#define INPIXEL rdr::CONCAT2E(U,BPPIN)
42#define OUTPIXEL rdr::CONCAT2E(U,BPPOUT)
43#define transSimpleINtoOUT CONCAT4E(transSimple,BPPIN,to,BPPOUT)
44#define transRGBINtoOUT CONCAT4E(transRGB,BPPIN,to,BPPOUT)
45#define transRGBCubeINtoOUT CONCAT4E(transRGBCube,BPPIN,to,BPPOUT)
46
47#if (BPPIN <= 16)
48
49// transSimpleINtoOUT uses a single table. This can be used for any incoming
50// and outgoing pixel formats, as long as the incoming pixel format is not too
51// large (for 16bpp, the table needs 64K entries).
52
53void transSimpleINtoOUT (void* table_,
54 const PixelFormat& inPF, void* inPtr, int inStride,
55 const PixelFormat& outPF, void* outPtr, int outStride,
56 int width, int height)
57{
58 OUTPIXEL* table = (OUTPIXEL*)table_;
59 INPIXEL* ip = (INPIXEL*)inPtr;
60 OUTPIXEL* op = (OUTPIXEL*)outPtr;
61 int inExtra = inStride - width;
62 int outExtra = outStride - width;
63
64 while (height > 0) {
65 OUTPIXEL* opEndOfRow = op + width;
66 while (op < opEndOfRow)
67 *op++ = table[*ip++];
68 ip += inExtra;
69 op += outExtra;
70 height--;
71 }
72}
73
74#endif
75
76#if (BPPIN >= 16)
77
78// transRGBINtoOUT uses three tables, one each for red, green and blue
79// components and adds the values to produce the result. This can be used
80// where a single table would be too large (e.g. 32bpp). It only works for a
81// trueColour incoming pixel format. Usually the outgoing pixel format is
82// trueColour, but we add rather than ORing the three values so that it is also
83// possible to generate an index into a colour cube. I believe that in most
84// cases adding is just as fast as ORing - if not then we should split this
85// into two different functions for efficiency.
86
87void transRGBINtoOUT (void* table,
88 const PixelFormat& inPF, void* inPtr, int inStride,
89 const PixelFormat& outPF, void* outPtr, int outStride,
90 int width, int height)
91{
92 OUTPIXEL* redTable = (OUTPIXEL*)table;
93 OUTPIXEL* greenTable = redTable + inPF.redMax + 1;
94 OUTPIXEL* blueTable = greenTable + inPF.greenMax + 1;
95 INPIXEL* ip = (INPIXEL*)inPtr;
96 OUTPIXEL* op = (OUTPIXEL*)outPtr;
97 int inExtra = inStride - width;
98 int outExtra = outStride - width;
99
100 while (height > 0) {
101 OUTPIXEL* opEndOfRow = op + width;
102 while (op < opEndOfRow) {
103 *op++ = (redTable [(*ip >> inPF.redShift) & inPF.redMax] +
104 greenTable[(*ip >> inPF.greenShift) & inPF.greenMax] +
105 blueTable [(*ip >> inPF.blueShift) & inPF.blueMax]);
106 ip++;
107 }
108 ip += inExtra;
109 op += outExtra;
110 height--;
111 }
112}
113
114// transRGBCubeINtoOUT is similar to transRGBINtoOUT but also looks up the
115// colour cube index in a fourth table to yield a pixel value.
116
117void transRGBCubeINtoOUT (void* table,
118 const PixelFormat& inPF, void* inPtr, int inStride,
119 const PixelFormat& outPF, void* outPtr,
120 int outStride, int width, int height)
121{
122 OUTPIXEL* redTable = (OUTPIXEL*)table;
123 OUTPIXEL* greenTable = redTable + inPF.redMax + 1;
124 OUTPIXEL* blueTable = greenTable + inPF.greenMax + 1;
125 OUTPIXEL* cubeTable = blueTable + inPF.blueMax + 1;
126 INPIXEL* ip = (INPIXEL*)inPtr;
127 OUTPIXEL* op = (OUTPIXEL*)outPtr;
128 int inExtra = inStride - width;
129 int outExtra = outStride - width;
130
131 while (height > 0) {
132 OUTPIXEL* opEndOfRow = op + width;
133 while (op < opEndOfRow) {
134 *op++ = cubeTable[(redTable [(*ip >> inPF.redShift) & inPF.redMax] +
135 greenTable[(*ip >> inPF.greenShift) & inPF.greenMax] +
136 blueTable [(*ip >> inPF.blueShift) & inPF.blueMax])];
137 ip++;
138 }
139 ip += inExtra;
140 op += outExtra;
141 height--;
142 }
143}
144
145#endif
146
147#undef INPIXEL
148#undef OUTPIXEL
149#undef transSimpleINtoOUT
150#undef transRGBINtoOUT
151#undef transRGBCubeINtoOUT