tabletrans24template.c 8.78 KB
Newer Older
dscho's avatar
dscho committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
/*
 * tabletranstemplate.c - template for translation using lookup tables.
 *
 * This file shouldn't be compiled.  It is included multiple times by
 * translate.c, each time with different definitions of the macros IN and OUT.
 *
 * For each pair of values IN and OUT, this file defines two functions for
 * translating a given rectangle of pixel data.  One uses a single lookup
 * table, and the other uses three separate lookup tables for the red, green
 * and blue values.
 *
 * I know this code isn't nice to read because of all the macros, but
 * efficiency is important here.
 */

/*
 *  OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
 *  Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.  
 *  All Rights Reserved.
 *
 *  This is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This software is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this software; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 *  USA.
 */

#if !defined(BPP)
#error "This file shouldn't be compiled."
#error "It is included as part of translate.c"
#endif

#if BPP == 24

/*
 * rfbTranslateWithSingleTableINtoOUT translates a rectangle of pixel data
 * using a single lookup table.
 */

static void
rfbTranslateWithSingleTable24to24 (char *table, rfbPixelFormat *in,
                                    rfbPixelFormat *out,
                                    char *iptr, char *optr,
                                    int bytesBetweenInputLines,
                                    int width, int height)
{
56 57
    uint8_t *ip = (uint8_t *)iptr;
    uint8_t *op = (uint8_t *)optr;
dscho's avatar
dscho committed
58
    int ipextra = bytesBetweenInputLines - width * 3;
59 60
    uint8_t *opLineEnd;
    uint8_t *t = (uint8_t *)table;
dscho's avatar
dscho committed
61
    int shift = rfbEndianTest?0:8;
62
    uint8_t c;
dscho's avatar
dscho committed
63 64 65 66 67

    while (height > 0) {
        opLineEnd = op + width*3;

        while (op < opLineEnd) {
68
	    *(uint32_t*)op = t[((*(uint32_t *)ip)>>shift)&0x00ffffff];
dscho's avatar
dscho committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
	    if(!rfbEndianTest)
	      memmove(op,op+1,3);
	    if (out->bigEndian != in->bigEndian) {
	      c = op[0]; op[0] = op[2]; op[2] = c;
	    }
	    op += 3;
	    ip += 3;
        }

        ip += ipextra;
        height--;
    }
}

/*
 * rfbTranslateWithRGBTablesINtoOUT translates a rectangle of pixel data
 * using three separate lookup tables for the red, green and blue values.
 */

static void
rfbTranslateWithRGBTables24to24 (char *table, rfbPixelFormat *in,
                                  rfbPixelFormat *out,
                                  char *iptr, char *optr,
                                  int bytesBetweenInputLines,
                                  int width, int height)
{
95 96
    uint8_t *ip = (uint8_t *)iptr;
    uint8_t *op = (uint8_t *)optr;
dscho's avatar
dscho committed
97
    int ipextra = bytesBetweenInputLines - width*3;
98 99 100 101 102
    uint8_t *opLineEnd;
    uint8_t *redTable = (uint8_t *)table;
    uint8_t *greenTable = redTable + 3*(in->redMax + 1);
    uint8_t *blueTable = greenTable + 3*(in->greenMax + 1);
    uint32_t outValue,inValue;
dscho's avatar
dscho committed
103 104 105 106 107 108
    int shift = rfbEndianTest?0:8;

    while (height > 0) {
        opLineEnd = op+3*width;

        while (op < opLineEnd) {
109
	    inValue = ((*(uint32_t *)ip)>>shift)&0x00ffffff;
dscho's avatar
dscho committed
110 111 112 113 114 115 116 117 118 119 120 121 122 123
            outValue = (redTable[(inValue >> in->redShift) & in->redMax] |
                       greenTable[(inValue >> in->greenShift) & in->greenMax] |
                       blueTable[(inValue >> in->blueShift) & in->blueMax]);
	    memcpy(op,&outValue,3);
	    op += 3;
            ip+=3;
        }
        ip += ipextra;
        height--;
    }
}

#else

124 125
#define IN_T CONCAT3E(uint,BPP,_t)
#define OUT_T CONCAT3E(uint,BPP,_t)
dscho's avatar
dscho committed
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
#define rfbTranslateWithSingleTable24toOUT \
                                CONCAT4E(rfbTranslateWithSingleTable,24,to,BPP)
#define rfbTranslateWithSingleTableINto24 \
                                CONCAT4E(rfbTranslateWithSingleTable,BPP,to,24)
#define rfbTranslateWithRGBTables24toOUT \
                                CONCAT4E(rfbTranslateWithRGBTables,24,to,BPP)
#define rfbTranslateWithRGBTablesINto24 \
                                CONCAT4E(rfbTranslateWithRGBTables,BPP,to,24)

/*
 * rfbTranslateWithSingleTableINtoOUT translates a rectangle of pixel data
 * using a single lookup table.
 */

static void
rfbTranslateWithSingleTable24toOUT (char *table, rfbPixelFormat *in,
                                    rfbPixelFormat *out,
                                    char *iptr, char *optr,
                                    int bytesBetweenInputLines,
                                    int width, int height)
{
147
    uint8_t *ip = (uint8_t *)iptr;
dscho's avatar
dscho committed
148
    OUT_T *op = (OUT_T *)optr;
dscho's avatar
dscho committed
149
    int ipextra = bytesBetweenInputLines - width*3;
dscho's avatar
dscho committed
150 151 152 153 154 155 156 157
    OUT_T *opLineEnd;
    OUT_T *t = (OUT_T *)table;
    int shift = rfbEndianTest?0:8;

    while (height > 0) {
        opLineEnd = op + width;

        while (op < opLineEnd) {
158
            *(op++) = t[((*(uint32_t *)ip)>>shift)&0x00ffffff];
dscho's avatar
dscho committed
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
	    ip+=3;
        }

        ip += ipextra;
        height--;
    }
}


/*
 * rfbTranslateWithRGBTablesINtoOUT translates a rectangle of pixel data
 * using three separate lookup tables for the red, green and blue values.
 */

static void
rfbTranslateWithRGBTables24toOUT (char *table, rfbPixelFormat *in,
                                  rfbPixelFormat *out,
                                  char *iptr, char *optr,
                                  int bytesBetweenInputLines,
                                  int width, int height)
{
180
    uint8_t *ip = (uint8_t *)iptr;
dscho's avatar
dscho committed
181
    OUT_T *op = (OUT_T *)optr;
dscho's avatar
dscho committed
182
    int ipextra = bytesBetweenInputLines - width*3;
dscho's avatar
dscho committed
183 184 185 186
    OUT_T *opLineEnd;
    OUT_T *redTable = (OUT_T *)table;
    OUT_T *greenTable = redTable + in->redMax + 1;
    OUT_T *blueTable = greenTable + in->greenMax + 1;
187
    uint32_t inValue;
dscho's avatar
dscho committed
188 189 190 191 192 193
    int shift = rfbEndianTest?0:8;

    while (height > 0) {
        opLineEnd = &op[width];

        while (op < opLineEnd) {
194
	    inValue = ((*(uint32_t *)ip)>>shift)&0x00ffffff;
dscho's avatar
dscho committed
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
            *(op++) = (redTable[(inValue >> in->redShift) & in->redMax] |
                       greenTable[(inValue >> in->greenShift) & in->greenMax] |
                       blueTable[(inValue >> in->blueShift) & in->blueMax]);
            ip+=3;
        }
        ip += ipextra;
        height--;
    }
}

/*
 * rfbTranslateWithSingleTableINto24 translates a rectangle of pixel data
 * using a single lookup table.
 */

static void
rfbTranslateWithSingleTableINto24 (char *table, rfbPixelFormat *in,
                                    rfbPixelFormat *out,
                                    char *iptr, char *optr,
                                    int bytesBetweenInputLines,
                                    int width, int height)
{
    IN_T *ip = (IN_T *)iptr;
218
    uint8_t *op = (uint8_t *)optr;
dscho's avatar
dscho committed
219
    int ipextra = bytesBetweenInputLines / sizeof(IN_T) - width;
220 221
    uint8_t *opLineEnd;
    uint8_t *t = (uint8_t *)table;
dscho's avatar
dscho committed
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249

    while (height > 0) {
        opLineEnd = op + width * 3;

        while (op < opLineEnd) {
	    memcpy(op,&t[3*(*(ip++))],3);
	    op += 3;
        }

        ip += ipextra;
        height--;
    }
}


/*
 * rfbTranslateWithRGBTablesINto24 translates a rectangle of pixel data
 * using three separate lookup tables for the red, green and blue values.
 */

static void
rfbTranslateWithRGBTablesINto24 (char *table, rfbPixelFormat *in,
                                  rfbPixelFormat *out,
                                  char *iptr, char *optr,
                                  int bytesBetweenInputLines,
                                  int width, int height)
{
    IN_T *ip = (IN_T *)iptr;
250
    uint8_t *op = (uint8_t *)optr;
dscho's avatar
dscho committed
251
    int ipextra = bytesBetweenInputLines / sizeof(IN_T) - width;
252 253 254 255 256
    uint8_t *opLineEnd;
    uint8_t *redTable = (uint8_t *)table;
    uint8_t *greenTable = redTable + 3*(in->redMax + 1);
    uint8_t *blueTable = greenTable + 3*(in->greenMax + 1);
    uint32_t outValue;
dscho's avatar
dscho committed
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281

    while (height > 0) {
        opLineEnd = op+3*width;

        while (op < opLineEnd) {
            outValue = (redTable[(*ip >> in->redShift) & in->redMax] |
                       greenTable[(*ip >> in->greenShift) & in->greenMax] |
                       blueTable[(*ip >> in->blueShift) & in->blueMax]);
	    memcpy(op,&outValue,3);
	    op += 3;
            ip++;
        }
        ip += ipextra;
        height--;
    }
}

#undef IN_T
#undef OUT_T
#undef rfbTranslateWithSingleTable24toOUT
#undef rfbTranslateWithRGBTables24toOUT
#undef rfbTranslateWithSingleTableINto24
#undef rfbTranslateWithRGBTablesINto24

#endif