diff options
-rw-r--r-- | pnmshow24.c | 90 | ||||
-rw-r--r-- | tableinit24.c | 157 | ||||
-rw-r--r-- | tabletrans24template.c | 281 |
3 files changed, 528 insertions, 0 deletions
diff --git a/pnmshow24.c b/pnmshow24.c new file mode 100644 index 0000000..bb6821e --- /dev/null +++ b/pnmshow24.c @@ -0,0 +1,90 @@ +#ifndef ALLOW24BPP +#error "I need the ALLOW24BPP flag to work" +#endif + +#include <stdio.h> +#include "rfb.h" +#include "keysym.h" + +void HandleKey(Bool down,KeySym key,rfbClientPtr cl) +{ + if(down && (key==XK_Escape || key=='q' || key=='Q')) + rfbCloseClient(cl); +} + +int main(int argc,char** argv) +{ + FILE* in=stdin; + int j,width,height,paddedWidth; + unsigned char buffer[1024]; + rfbScreenInfoPtr rfbScreen; + + if(argc>1) { + in=fopen(argv[1],"rb"); + if(!in) { + printf("Couldn't find file %s.\n",argv[1]); + exit(1); + } + } + + fgets(buffer,1024,in); + if(strncmp(buffer,"P6",2)) { + printf("Not a ppm.\n"); + exit(2); + } + + /* skip comments */ + do { + fgets(buffer,1024,in); + } while(buffer[0]=='#'); + + /* get width & height */ + sscanf(buffer,"%d %d",&width,&height); + fprintf(stderr,"Got width %d and height %d.\n",width,height); + fgets(buffer,1024,in); + + /* vncviewers have problems with widths which are no multiple of 4. */ + paddedWidth = width; + + /* if your vncviewer doesn't have problems with a width + which is not a multiple of 4, you can comment this. */ + if(width&3) + paddedWidth+=4-(width&3); + + /* initialize data for vnc server */ + rfbScreen = rfbGetScreen(argc,argv,paddedWidth,height,8,3,3); + if(argc>1) + rfbScreen->desktopName = argv[1]; + else + rfbScreen->desktopName = "Picture"; + rfbScreen->rfbAlwaysShared = TRUE; + rfbScreen->kbdAddEvent = HandleKey; + + /* enable http */ + rfbScreen->httpDir = "./classes"; + + /* allocate picture and read it */ + rfbScreen->frameBuffer = (char*)malloc(paddedWidth*3*height); + fread(rfbScreen->frameBuffer,width*3,height,in); + fclose(in); + + /* pad to paddedWidth */ + if(width != paddedWidth) { + int padCount = 3*(paddedWidth - width); + for(j=height-1;j>=0;j--) { + memmove(rfbScreen->frameBuffer+3*paddedWidth*j, + rfbScreen->frameBuffer+3*width*j, + 3*width); + memset(rfbScreen->frameBuffer+3*paddedWidth*(j+1)-padCount, + 0,padCount); + } + } + + /* initialize server */ + rfbInitServer(rfbScreen); + + /* run event loop */ + rfbRunEventLoop(rfbScreen,40000,FALSE); + + return(0); +} diff --git a/tableinit24.c b/tableinit24.c new file mode 100644 index 0000000..144d3a3 --- /dev/null +++ b/tableinit24.c @@ -0,0 +1,157 @@ +/* + 24 bit + */ + +/* + * 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. + */ + +static void +rfbInitOneRGBTable24 (CARD8 *table, int inMax, int outMax, int outShift,int swap); + + +static void +rfbInitColourMapSingleTable24(char **table, rfbPixelFormat *in, + rfbPixelFormat *out,rfbColourMap* colourMap) +{ + CARD32 i, r, g, b, outValue; + CARD8 *t; + CARD8 c; + int nEntries = 1 << in->bitsPerPixel; + int shift = colourMap->is16?16:8; + + if (*table) free(*table); + *table = (char *)malloc(nEntries * 3 + 1); + t = (CARD8 *)*table; + + for (i = 0; i < nEntries; i++) { + r = g = b = 0; + if(i < colourMap->count) { + if(colourMap->is16) { + r = colourMap->data.shorts[3*i+0]; + g = colourMap->data.shorts[3*i+1]; + b = colourMap->data.shorts[3*i+2]; + } else { + r = colourMap->data.bytes[3*i+0]; + g = colourMap->data.bytes[3*i+1]; + b = colourMap->data.bytes[3*i+2]; + } + } + outValue = ((((r * (1 + out->redMax)) >> shift) << out->redShift) | + (((g * (1 + out->greenMax)) >> shift) << out->greenShift) | + (((b * (1 + out->blueMax)) >> shift) << out->blueShift)); + *(CARD32*)&t[3*i] = outValue; + if(!rfbEndianTest) + memmove(t+3*i,t+3*i+1,3); + if (out->bigEndian != in->bigEndian) { + c = t[3*i]; t[3*i] = t[3*i+2]; t[3*i+2] = c; + } + } +} + +/* + * rfbInitTrueColourSingleTable sets up a single lookup table for truecolour + * translation. + */ + +static void +rfbInitTrueColourSingleTable24 (char **table, rfbPixelFormat *in, + rfbPixelFormat *out) +{ + int i,outValue; + int inRed, inGreen, inBlue, outRed, outGreen, outBlue; + CARD8 *t; + CARD8 c; + int nEntries = 1 << in->bitsPerPixel; + + if (*table) free(*table); + *table = (char *)xalloc(nEntries * 3 + 1); + t = (CARD8 *)*table; + + for (i = 0; i < nEntries; i++) { + inRed = (i >> in->redShift) & in->redMax; + inGreen = (i >> in->greenShift) & in->greenMax; + inBlue = (i >> in->blueShift) & in->blueMax; + + outRed = (inRed * out->redMax + in->redMax / 2) / in->redMax; + outGreen = (inGreen * out->greenMax + in->greenMax / 2) / in->greenMax; + outBlue = (inBlue * out->blueMax + in->blueMax / 2) / in->blueMax; + + outValue = ((outRed << out->redShift) | + (outGreen << out->greenShift) | + (outBlue << out->blueShift)); + *(CARD32*)&t[3*i] = outValue; + if(!rfbEndianTest) + memmove(t+3*i,t+3*i+1,3); + if (out->bigEndian != in->bigEndian) { + c = t[3*i]; t[3*i] = t[3*i+2]; t[3*i+2] = c; + } + } +} + + +/* + * rfbInitTrueColourRGBTables sets up three separate lookup tables for the + * red, green and blue values. + */ + +static void +rfbInitTrueColourRGBTables24 (char **table, rfbPixelFormat *in, + rfbPixelFormat *out) +{ + CARD8 *redTable; + CARD8 *greenTable; + CARD8 *blueTable; + + if (*table) free(*table); + *table = (char *)xalloc((in->redMax + in->greenMax + in->blueMax + 3) + * 3 + 1); + redTable = (CARD8 *)*table; + greenTable = redTable + 3*(in->redMax + 1); + blueTable = greenTable + 3*(in->greenMax + 1); + + rfbInitOneRGBTable24 (redTable, in->redMax, out->redMax, + out->redShift, (out->bigEndian != in->bigEndian)); + rfbInitOneRGBTable24 (greenTable, in->greenMax, out->greenMax, + out->greenShift, (out->bigEndian != in->bigEndian)); + rfbInitOneRGBTable24 (blueTable, in->blueMax, out->blueMax, + out->blueShift, (out->bigEndian != in->bigEndian)); +} + +static void +rfbInitOneRGBTable24 (CARD8 *table, int inMax, int outMax, int outShift, + int swap) +{ + int i; + int nEntries = inMax + 1; + CARD32 outValue; + CARD8 c; + + for (i = 0; i < nEntries; i++) { + outValue = ((i * outMax + inMax / 2) / inMax) << outShift; + *(CARD32 *)&table[3*i] = outValue; + if(!rfbEndianTest) + memmove(table+3*i,table+3*i+1,3); + if (swap) { + c = table[3*i]; table[3*i] = table[3*i+2]; + table[3*i+2] = c; + } + } +} diff --git a/tabletrans24template.c b/tabletrans24template.c new file mode 100644 index 0000000..0dee0d3 --- /dev/null +++ b/tabletrans24template.c @@ -0,0 +1,281 @@ +/* + * 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) +{ + CARD8 *ip = (CARD8 *)iptr; + CARD8 *op = (CARD8 *)optr; + int ipextra = bytesBetweenInputLines / 3 - width; + CARD8 *opLineEnd; + CARD8 *t = (CARD8 *)table; + int shift = rfbEndianTest?0:8; + CARD8 c; + + while (height > 0) { + opLineEnd = op + width*3; + + while (op < opLineEnd) { + *(CARD32*)op = t[((*(CARD32 *)ip)>>shift)&0x00ffffff]; + 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) +{ + CARD8 *ip = (CARD8 *)iptr; + CARD8 *op = (CARD8 *)optr; + int ipextra = bytesBetweenInputLines / 3 - width; + CARD8 *opLineEnd; + CARD8 *redTable = (CARD8 *)table; + CARD8 *greenTable = redTable + 3*(in->redMax + 1); + CARD8 *blueTable = greenTable + 3*(in->greenMax + 1); + CARD32 outValue,inValue; + int shift = rfbEndianTest?0:8; + + while (height > 0) { + opLineEnd = op+3*width; + + while (op < opLineEnd) { + inValue = ((*(CARD32 *)ip)>>shift)&0x00ffffff; + 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 + +#define IN_T CONCAT2E(CARD,BPP) +#define OUT_T CONCAT2E(CARD,BPP) +#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) +{ + CARD8 *ip = (CARD8 *)iptr; + OUT_T *op = (OUT_T *)optr; + int ipextra = bytesBetweenInputLines / 3 - width; + OUT_T *opLineEnd; + OUT_T *t = (OUT_T *)table; + int shift = rfbEndianTest?0:8; + + while (height > 0) { + opLineEnd = op + width; + + while (op < opLineEnd) { + *(op++) = t[((*(CARD32 *)ip)>>shift)&0x00ffffff]; + 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) +{ + CARD8 *ip = (CARD8 *)iptr; + OUT_T *op = (OUT_T *)optr; + int ipextra = bytesBetweenInputLines / 3 - width; + OUT_T *opLineEnd; + OUT_T *redTable = (OUT_T *)table; + OUT_T *greenTable = redTable + in->redMax + 1; + OUT_T *blueTable = greenTable + in->greenMax + 1; + CARD32 inValue; + int shift = rfbEndianTest?0:8; + + while (height > 0) { + opLineEnd = &op[width]; + + while (op < opLineEnd) { + inValue = ((*(CARD32 *)ip)>>shift)&0x00ffffff; + *(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; + CARD8 *op = (CARD8 *)optr; + int ipextra = bytesBetweenInputLines / sizeof(IN_T) - width; + CARD8 *opLineEnd; + CARD8 *t = (CARD8 *)table; + + 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; + CARD8 *op = (CARD8 *)optr; + int ipextra = bytesBetweenInputLines / sizeof(IN_T) - width; + CARD8 *opLineEnd; + CARD8 *redTable = (CARD8 *)table; + CARD8 *greenTable = redTable + 3*(in->redMax + 1); + CARD8 *blueTable = greenTable + 3*(in->greenMax + 1); + CARD32 outValue; + + 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 |