summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pnmshow24.c90
-rw-r--r--tableinit24.c157
-rw-r--r--tabletrans24template.c281
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