Constantin Kaplinsky | de179d4 | 2006-04-16 06:53:44 +0000 | [diff] [blame] | 1 | /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. |
| 2 | * |
Constantin Kaplinsky | 47ed8d3 | 2004-10-08 09:43:57 +0000 | [diff] [blame] | 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 | // 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 | |
| 53 | void 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 | |
| 87 | void 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 | |
| 117 | void 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 |