From 7ea0d024cb1dbc7490892ebde7ee9f3b48aa9fd2 Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Fri, 15 Oct 2004 16:22:06 +0000
Subject: compiling, non functional version of a unit test for encodings

---
 test/tight-1.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 211 insertions(+), 18 deletions(-)

diff --git a/test/tight-1.c b/test/tight-1.c
index e8b9b79..af20178 100644
--- a/test/tight-1.c
+++ b/test/tight-1.c
@@ -2,30 +2,223 @@
 #include <rfb/rfb.h>
 #include <rfb/rfbclient.h>
 
+#ifndef LIBVNCSERVER_HAVE_LIBTHREAD
+//#error This test need pthread support (otherwise the client blocks the client)
+#endif
+
+MUTEX(frameBufferMutex);
+
+int testEncodings[]={
+	rfbEncodingRaw,
+	rfbEncodingRRE,
+	rfbEncodingCoRRE,
+	rfbEncodingHextile,
+#ifdef LIBVNCSERVER_HAVE_LIBZ
+	rfbEncodingZlib,
+	rfbEncodingZlibHex,
+	rfbEncodingZRLE,
+#ifdef LIBVNCSERVER_HAVE_LIBJPEG
+	rfbEncodingTight,
+#endif
+#endif
+	0
+};
+
+#define NUMBER_OF_ENCODINGS_TO_TEST (sizeof(testEncodings)/sizeof(int)-1)
+
+/* Here come the variables/functions to handle the test output */
+
+struct { int x1,y1,x2,y2; } lastUpdateRect;
+unsigned int statistics[NUMBER_OF_ENCODINGS_TO_TEST];
+unsigned int totalFailed;
+unsigned int countGotUpdate;
+MUTEX(statisticsMutex);
+
+void initStatistics() {
+	memset(statistics,0,sizeof(int)*NUMBER_OF_ENCODINGS_TO_TEST);
+	totalFailed=0;
+	INIT_MUTEX(statisticsMutex);
+}
+
+void updateServerStatistics(int x1,int y1,int x2,int y2) {
+	LOCK(statisticsMutex);
+	countGotUpdate=0;
+	lastUpdateRect.x1=x1;
+	lastUpdateRect.y1=y1;
+	lastUpdateRect.x2=x2;
+	lastUpdateRect.y2=y2;
+	UNLOCK(statisticsMutex);
+}
+
+void updateStatistics(int encodingIndex,rfbBool failed) {
+	LOCK(statisticsMutex);
+	if(failed) {
+		statistics[encodingIndex]++;
+		totalFailed++;
+	}
+	countGotUpdate++;
+	UNLOCK(statisticsMutex);
+}
+
+	
+
+/* Here begin the functions for the client. They will be called in a
+ * pthread. */
+
+/* maxDelta=0 means they are expected to match exactly;
+ * maxDelta>0 means that the average difference must be lower than maxDelta */
+rfbBool doFramebuffersMatch(rfbScreenInfo* server,rfbClient* client,
+		int maxDelta)
+{
+	int i,j,k;
+	unsigned int total=0,diff=0;
+	if(server->width!=client->width || server->height!=client->height)
+		return FALSE;
+	LOCK(frameBufferMutex);
+	/* TODO: write unit test for colour transformation, use here, too */
+	for(i=0;i<server->width;i++)
+		for(j=0;j<server->height;j++)
+			for(k=0;k<server->serverFormat.bitsPerPixel/8;k++) {
+				unsigned char s=server->frameBuffer[k+i*4+j*server->paddedWidthInBytes];
+				unsigned char cl=client->frameBuffer[k+i*4+j*client->width];
+				
+				if(maxDelta==0 && s!=cl) {
+					UNLOCK(frameBufferMutex);
+					return FALSE;
+				} else {
+					total++;
+					diff+=(s>cl?s-cl:cl-s);
+				}
+			}
+	UNLOCK(frameBufferMutex);
+	if(maxDelta>0 && diff/total>=maxDelta)
+		return FALSE;
+	return TRUE;
+}
+
+static rfbBool resize(rfbClient* cl) {
+	if(cl->frameBuffer)
+		free(cl->frameBuffer);
+	cl->frameBuffer=(char*)malloc(cl->width*cl->height*cl->format.bitsPerPixel/8);
+}
+
+typedef struct clientData {
+	int encodingIndex;
+	rfbScreenInfo* server;
+} clientData;
+
+static void update(rfbClient* client,int x,int y,int w,int h) {
+	clientData* cd=(clientData*)client->clientData;
+	int maxDelta=0;
+
+	if(testEncodings[cd->encodingIndex]==rfbEncodingTight)
+		maxDelta=5;
+	
+	/* TODO: check if dimensions match with marked rectangle */
+
+	/* only check if this was the last update */
+	if(x+w!=lastUpdateRect.x2 || y+h!=lastUpdateRect.y2)
+		return;
+	updateStatistics(cd->encodingIndex,
+			!doFramebuffersMatch(cd->server,client,maxDelta));
+}
+
+static void* clientLoop(void* data) {
+	rfbClient* client=(rfbClient*)data;
+	int argc=2;
+	char* argv[2]={"client",":0"};
+	if(!rfbInitClient(client,&argc,argv))
+		return 0;
+	while(1) {
+		if(WaitForMessage(client,50)>=0)
+			if(!HandleRFBServerMessage(client))
+				break;
+	}
+	if(client->frameBuffer)
+		free(client->frameBuffer);
+	rfbClientCleanup(client);
+	return 0;
+}
+
+static void startClient(int encodingIndex,rfbScreenInfo* server) {
+	rfbClient* client=rfbGetClient(8,3,4);
+	clientData* cd;
+	pthread_t clientThread;
+	
+	client->clientData=malloc(sizeof(clientData));
+	client->MallocFrameBuffer=resize;
+	client->GotFrameBufferUpdate=update;
+
+	cd=(clientData*)client->clientData;
+	cd->encodingIndex=encodingIndex;
+	cd->server=server;
+	
+	pthread_create(&clientThread,NULL,clientLoop,(void*)client);
+}
+
+/* Here begin the server functions */
+
+static void idle(rfbScreenInfo* server)
+{
+	int c;
+	rfbBool goForward;
+
+	LOCK(statisticsMutex);
+	goForward=(countGotUpdate==NUMBER_OF_ENCODINGS_TO_TEST);
+	UNLOCK(statisticsMutex);
+	if(!goForward)
+		return;
+
+	LOCK(frameBufferMutex);
+	for(c=0;c<3;c++) {
+		int x1=(rand()%server->width),x2=(rand()%server->width),
+		y1=(rand()%server->height),y2=(rand()%server->height);
+		int i,j;
+		if(x1>x2) { i=x1; x1=x2; x2=i; }
+		if(y1>y2) { i=y1; y1=y2; y2=i; }
+		for(i=x1;i<=x2;i++)
+			for(j=y1;j<=y2;j++)
+				server->frameBuffer[i*4+c+j*server->paddedWidthInBytes]=255*(i-x1+j-y1+1)/(x2-x1+y2-y1+1);
+		rfbMarkRectAsModified(server,x1,y1,x2+1,y2+1);
+	}
+	UNLOCK(frameBufferMutex);
+}
+
+//TODO: pthread'ize the client. otherwise server and client block each
+//other
 int main(int argc,char** argv)
 {                                                                
-  int i,j;
-  time_t t=time(0);
+	int i,j;
+	time_t t;
 
-  rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,400,300,8,3,4);
-  rfbClient* client=rfbGetClient(8,3,4);
+	/* Initialize server */
+	rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,400,300,8,3,4);
 
-  server->frameBuffer=malloc(400*300*4);
-  for(j=0;j<400*300*4;j++)
-    server->frameBuffer[j]=j;
-  rfbInitServer(server);           
-  while(time(0)-t<20) {
+	server->frameBuffer=malloc(400*300*4);
+	for(j=0;j<400*300*4;j++)
+		server->frameBuffer[j]=j;
+	rfbInitServer(server);
+	rfbProcessEvents(server,50);
 
-    for(j=0;j<400;j+=10)
-      for(i=0;i<300;i+=10)
-	rfbMarkRectAsModified(server,i,j,i+5,j+5);
+	/* Initialize clients */
+	for(i=0;i<NUMBER_OF_ENCODINGS_TO_TEST;i++)
+		startClient(i,server);
+	
+	t=time(0);
+	/* test 20 seconds */
+	while(time(0)-t<20) {
 
-    rfbProcessEvents(server,5000);
-  }
+		idle(server);
 
-  free(server->frameBuffer);
-  rfbScreenCleanup(server);
-  rfbClientCleanup(client);
+		rfbProcessEvents(server,50);
+	}
 
-  return(0);
+	free(server->frameBuffer);
+	rfbScreenCleanup(server);
+
+	printf("Statistics: %d failed\n",totalFailed);
+	if(totalFailed)
+		return 1;
+	return(0);
 }
+
-- 
cgit v1.2.3

