LibVNCServer/LibVNCClient
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pnmshow.c
Go to the documentation of this file.
1 
4 #include <stdio.h>
5 #include <rfb/rfb.h>
6 #include <rfb/keysym.h>
7 
8 #ifndef HAVE_HANDLEKEY
9 static void HandleKey(rfbBool down,rfbKeySym key,rfbClientPtr cl)
10 {
11  if(down && (key==XK_Escape || key=='q' || key=='Q'))
12  rfbCloseClient(cl);
13 }
14 #endif
15 
16 int main(int argc,char** argv)
17 {
18  FILE* in=stdin;
19  int i,j,k,l,width,height,paddedWidth;
20  char buffer[1024];
21  rfbScreenInfoPtr rfbScreen;
22  enum { BW, GRAY, TRUECOLOUR } picType=TRUECOLOUR;
23  int bytesPerPixel,bitsPerPixelInFile;
24 
25  if(argc>1) {
26  in=fopen(argv[1],"rb");
27  if(!in) {
28  printf("Couldn't find file %s.\n",argv[1]);
29  exit(1);
30  }
31  }
32 
33  fgets(buffer,1024,in);
34  if(!strncmp(buffer,"P6",2)) {
35  picType=TRUECOLOUR;
36  bytesPerPixel=4; bitsPerPixelInFile=3*8;
37  } else if(!strncmp(buffer,"P5",2)) {
38  picType=GRAY;
39  bytesPerPixel=1; bitsPerPixelInFile=1*8;
40  } else if(!strncmp(buffer,"P4",2)) {
41  picType=BW;
42  bytesPerPixel=1; bitsPerPixelInFile=1;
43  } else {
44  printf("Not a ppm.\n");
45  exit(2);
46  }
47 
48  /* skip comments */
49  do {
50  fgets(buffer,1024,in);
51  } while(buffer[0]=='#');
52 
53  /* get width & height */
54  sscanf(buffer,"%d %d",&width,&height);
55  rfbLog("Got width %d and height %d.\n",width,height);
56  if(picType!=BW)
57  fgets(buffer,1024,in);
58  else
59  width=1+((width-1)|7);
60 
61  /* vncviewers have problems with widths which are no multiple of 4. */
62  paddedWidth = width;
63  if(width&3)
64  paddedWidth+=4-(width&3);
65 
66  /* initialize data for vnc server */
67  rfbScreen = rfbGetScreen(&argc,argv,paddedWidth,height,8,(bitsPerPixelInFile+7)/8,bytesPerPixel);
68  if(!rfbScreen)
69  return 0;
70  if(argc>1)
71  rfbScreen->desktopName = argv[1];
72  else
73  rfbScreen->desktopName = "Picture";
74  rfbScreen->alwaysShared = TRUE;
75  rfbScreen->kbdAddEvent = HandleKey;
76 
77  /* enable http */
78  rfbScreen->httpDir = "../webclients";
79 
80  /* allocate picture and read it */
81  rfbScreen->frameBuffer = (char*)malloc(paddedWidth*bytesPerPixel*height);
82  fread(rfbScreen->frameBuffer,width*bitsPerPixelInFile/8,height,in);
83  fclose(in);
84 
85  if(picType!=TRUECOLOUR) {
86  rfbScreen->serverFormat.trueColour=FALSE;
87  rfbScreen->colourMap.count=256;
88  rfbScreen->colourMap.is16=FALSE;
89  rfbScreen->colourMap.data.bytes=malloc(256*3);
90  for(i=0;i<256;i++)
91  memset(rfbScreen->colourMap.data.bytes+3*i,i,3);
92  }
93 
94  switch(picType) {
95  case TRUECOLOUR:
96  /* correct the format to 4 bytes instead of 3 (and pad to paddedWidth) */
97  for(j=height-1;j>=0;j--) {
98  for(i=width-1;i>=0;i--)
99  for(k=2;k>=0;k--)
100  rfbScreen->frameBuffer[(j*paddedWidth+i)*4+k]=
101  rfbScreen->frameBuffer[(j*width+i)*3+k];
102  for(i=width*4;i<paddedWidth*4;i++)
103  rfbScreen->frameBuffer[j*paddedWidth*4+i]=0;
104  }
105  break;
106  case GRAY:
107  break;
108  case BW:
109  /* correct the format from 1 bit to 8 bits */
110  for(j=height-1;j>=0;j--)
111  for(i=width-1;i>=0;i-=8) {
112  l=(unsigned char)rfbScreen->frameBuffer[(j*width+i)/8];
113  for(k=7;k>=0;k--)
114  rfbScreen->frameBuffer[j*paddedWidth+i+7-k]=(l&(1<<k))?0:255;
115  }
116  break;
117  }
118 
119  /* initialize server */
120  rfbInitServer(rfbScreen);
121 
122  /* run event loop */
123  rfbRunEventLoop(rfbScreen,40000,FALSE);
124 
125  return(0);
126 }