diff -Nru LibVNCServer-0.9.1/libvncserver/rfbregion.c x11vnc-0.9.5/libvncserver/rfbregion.c --- LibVNCServer-0.9.1/libvncserver/rfbregion.c 2005-05-15 16:57:53.000000000 +0200 +++ x11vnc-0.9.5/libvncserver/rfbregion.c 2008-05-08 02:54:27.000000000 +0200 @@ -620,8 +620,8 @@ sraRgnPopRect(sraRegion *rgn, sraRect *rect, unsigned long flags) { sraSpan *vcurr, *hcurr; sraSpan *vend, *hend; - rfbBool right2left = flags & 2; - rfbBool bottom2top = flags & 1; + rfbBool right2left = (flags & 2) == 2; + rfbBool bottom2top = (flags & 1) == 1; /* - Pick correct order */ if (bottom2top) { diff -Nru LibVNCServer-0.9.1/libvncserver/rfbserver.c x11vnc-0.9.5/libvncserver/rfbserver.c --- LibVNCServer-0.9.1/libvncserver/rfbserver.c 2007-05-19 05:17:58.000000000 +0200 +++ x11vnc-0.9.5/libvncserver/rfbserver.c 2008-06-24 20:46:24.000000000 +0200 @@ -74,6 +74,8 @@ #include /* errno */ #include +/* strftime() */ +#include #ifdef __MINGW32__ static int compat_mkdir(const char *path, int mode) @@ -367,9 +369,9 @@ UNLOCK(rfbClientListMutex); #ifdef LIBVNCSERVER_HAVE_LIBZ + cl->tightQualityLevel = -1; #ifdef LIBVNCSERVER_HAVE_LIBJPEG cl->tightCompressLevel = TIGHT_DEFAULT_COMPRESSION; - cl->tightQualityLevel = -1; { int i; for (i = 0; i < 4; i++) @@ -699,8 +701,10 @@ rfbProcessClientInitMessage(rfbClientPtr cl) { rfbClientInitMsg ci; - char buf[256]; - rfbServerInitMsg *si = (rfbServerInitMsg *)buf; + union { + char buf[256]; + rfbServerInitMsg si; + } u; int len, n; rfbClientIteratorPtr iterator; rfbClientPtr otherCl; @@ -715,20 +719,20 @@ return; } - memset(buf,0,sizeof(buf)); + memset(u.buf,0,sizeof(u.buf)); - si->framebufferWidth = Swap16IfLE(cl->screen->width); - si->framebufferHeight = Swap16IfLE(cl->screen->height); - si->format = cl->screen->serverFormat; - si->format.redMax = Swap16IfLE(si->format.redMax); - si->format.greenMax = Swap16IfLE(si->format.greenMax); - si->format.blueMax = Swap16IfLE(si->format.blueMax); - - strncpy(buf + sz_rfbServerInitMsg, cl->screen->desktopName, 127); - len = strlen(buf + sz_rfbServerInitMsg); - si->nameLength = Swap32IfLE(len); + u.si.framebufferWidth = Swap16IfLE(cl->screen->width); + u.si.framebufferHeight = Swap16IfLE(cl->screen->height); + u.si.format = cl->screen->serverFormat; + u.si.format.redMax = Swap16IfLE(u.si.format.redMax); + u.si.format.greenMax = Swap16IfLE(u.si.format.greenMax); + u.si.format.blueMax = Swap16IfLE(u.si.format.blueMax); + + strncpy(u.buf + sz_rfbServerInitMsg, cl->screen->desktopName, 127); + len = strlen(u.buf + sz_rfbServerInitMsg); + u.si.nameLength = Swap32IfLE(len); - if (rfbWriteExact(cl, buf, sz_rfbServerInitMsg + len) < 0) { + if (rfbWriteExact(cl, u.buf, sz_rfbServerInitMsg + len) < 0) { rfbLogPerror("rfbProcessClientInitMessage: write"); rfbCloseClient(cl); return; @@ -903,15 +907,6 @@ -static void rfbSendSupporteddEncodings_SendEncoding(rfbClientPtr cl, uint32_t enc) -{ - uint32_t nSwapped=0; - nSwapped = Swap32IfLE(enc); - memcpy(&cl->updateBuf[cl->ublen], (char *)&nSwapped, sizeof(nSwapped)); - cl->ublen+=sizeof(nSwapped); -} - - /* * Send rfbEncodingSupportedEncodings. */ @@ -920,21 +915,38 @@ rfbSendSupportedEncodings(rfbClientPtr cl) { rfbFramebufferUpdateRectHeader rect; - uint16_t nEncodings=0; - - /* think rfbSetEncodingsMsg */ - - /* TODO: dynamic way of doing this */ - nEncodings=16; + static uint32_t supported[] = { + rfbEncodingRaw, + rfbEncodingCopyRect, + rfbEncodingRRE, + rfbEncodingCoRRE, + rfbEncodingHextile, #ifdef LIBVNCSERVER_HAVE_LIBZ - nEncodings += 2; + rfbEncodingZlib, + rfbEncodingZRLE, + rfbEncodingZYWRLE, #endif -#ifdef LIBVNCSERVER_HAVE_LIBZ - nEncodings++; +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + rfbEncodingTight, #endif + rfbEncodingUltra, + rfbEncodingUltraZip, + rfbEncodingXCursor, + rfbEncodingRichCursor, + rfbEncodingPointerPos, + rfbEncodingLastRect, + rfbEncodingNewFBSize, + rfbEncodingKeyboardLedState, + rfbEncodingSupportedMessages, + rfbEncodingSupportedEncodings, + rfbEncodingServerIdentity, + }; + uint32_t nEncodings = sizeof(supported) / sizeof(supported[0]), i; + + /* think rfbSetEncodingsMsg */ if (cl->ublen + sz_rfbFramebufferUpdateRectHeader - + (nEncodings*sizeof(uint32_t)) > UPDATE_BUF_SIZE) { + + (nEncodings * sizeof(uint32_t)) > UPDATE_BUF_SIZE) { if (!rfbSendUpdateBuf(cl)) return FALSE; } @@ -949,29 +961,11 @@ sz_rfbFramebufferUpdateRectHeader); cl->ublen += sz_rfbFramebufferUpdateRectHeader; - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingRaw); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingCopyRect); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingRRE); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingCoRRE); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingHextile); -#ifdef LIBVNCSERVER_HAVE_LIBZ - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingZlib); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingTight); -#endif -#ifdef LIBVNCSERVER_HAVE_LIBZ - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingZRLE); -#endif - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingUltra); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingUltraZip); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingXCursor); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingRichCursor); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingPointerPos); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingLastRect); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingNewFBSize); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingKeyboardLedState); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingSupportedMessages); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingSupportedEncodings); - rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingServerIdentity); + for (i = 0; i < nEncodings; i++) { + uint32_t encoding = Swap32IfLE(supported[i]); + memcpy(&cl->updateBuf[cl->ublen], (char *)&encoding, sizeof(encoding)); + cl->ublen += sizeof(encoding); + } rfbStatRecordEncodingSent(cl, rfbEncodingSupportedEncodings, sz_rfbFramebufferUpdateRectHeader+(nEncodings * sizeof(uint32_t)), @@ -1906,6 +1900,7 @@ #ifdef LIBVNCSERVER_HAVE_LIBZ case rfbEncodingZlib: case rfbEncodingZRLE: + case rfbEncodingZYWRLE: #ifdef LIBVNCSERVER_HAVE_LIBJPEG case rfbEncodingTight: #endif @@ -1998,12 +1993,12 @@ cl->tightCompressLevel = enc & 0x0F; rfbLog("Using compression level %d for client %s\n", cl->tightCompressLevel, cl->host); +#endif } else if ( enc >= (uint32_t)rfbEncodingQualityLevel0 && enc <= (uint32_t)rfbEncodingQualityLevel9 ) { cl->tightQualityLevel = enc & 0x0F; rfbLog("Using image quality level %d for client %s\n", cl->tightQualityLevel, cl->host); -#endif } else #endif { @@ -2636,7 +2631,7 @@ rows = (h-1)/cl->correMaxHeight+1; nUpdateRegionRects += rectsPerRow*rows; } - sraRgnReleaseIterator(i); + sraRgnReleaseIterator(i); i=NULL; } else if (cl->preferredEncoding == rfbEncodingUltra) { nUpdateRegionRects = 0; @@ -2650,7 +2645,7 @@ rfbScaledCorrection(cl->screen, cl->scaledScreen, &x, &y, &w, &h, "rfbSendFramebufferUpdate"); nUpdateRegionRects += (((h-1) / (ULTRA_MAX_SIZE( w ) / w)) + 1); } - sraRgnReleaseIterator(i); + sraRgnReleaseIterator(i); i=NULL; #ifdef LIBVNCSERVER_HAVE_LIBZ } else if (cl->preferredEncoding == rfbEncodingZlib) { nUpdateRegionRects = 0; @@ -2665,7 +2660,7 @@ rfbScaledCorrection(cl->screen, cl->scaledScreen, &x, &y, &w, &h, "rfbSendFramebufferUpdate"); nUpdateRegionRects += (((h-1) / (ZLIB_MAX_SIZE( w ) / w)) + 1); } - sraRgnReleaseIterator(i); + sraRgnReleaseIterator(i); i=NULL; #ifdef LIBVNCSERVER_HAVE_LIBJPEG } else if (cl->preferredEncoding == rfbEncodingTight) { nUpdateRegionRects = 0; @@ -2686,7 +2681,7 @@ } nUpdateRegionRects += n; } - sraRgnReleaseIterator(i); + sraRgnReleaseIterator(i); i=NULL; #endif #endif } else { @@ -2804,12 +2799,17 @@ #endif #ifdef LIBVNCSERVER_HAVE_LIBZ case rfbEncodingZRLE: + case rfbEncodingZYWRLE: if (!rfbSendRectEncodingZRLE(cl, x, y, w, h)) goto updateFailed; break; #endif } } + if (i) { + sraRgnReleaseIterator(i); + i = NULL; + } if ( nUpdateRegionRects == 0xFFFF && !rfbSendLastRectMarker(cl) ) @@ -3066,12 +3066,20 @@ int nColours) { char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2]; - rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf; - uint16_t *rgb = (uint16_t *)(&buf[sz_rfbSetColourMapEntriesMsg]); + char *wbuf = buf; + rfbSetColourMapEntriesMsg *scme; + uint16_t *rgb; rfbColourMap* cm = &cl->screen->colourMap; - int i, len; + if (nColours > 256) { + /* some rare hardware has, e.g., 4096 colors cells: PseudoColor:12 */ + wbuf = (char *) malloc(sz_rfbSetColourMapEntriesMsg + nColours * 3 * 2); + } + + scme = (rfbSetColourMapEntriesMsg *)wbuf; + rgb = (uint16_t *)(&wbuf[sz_rfbSetColourMapEntriesMsg]); + scme->type = rfbSetColourMapEntries; scme->firstColour = Swap16IfLE(firstColour); @@ -3086,22 +3094,24 @@ rgb[i*3+1] = Swap16IfLE(cm->data.shorts[i*3+1]); rgb[i*3+2] = Swap16IfLE(cm->data.shorts[i*3+2]); } else { - rgb[i*3] = Swap16IfLE(cm->data.bytes[i*3]); - rgb[i*3+1] = Swap16IfLE(cm->data.bytes[i*3+1]); - rgb[i*3+2] = Swap16IfLE(cm->data.bytes[i*3+2]); + rgb[i*3] = Swap16IfLE((unsigned short)cm->data.bytes[i*3]); + rgb[i*3+1] = Swap16IfLE((unsigned short)cm->data.bytes[i*3+1]); + rgb[i*3+2] = Swap16IfLE((unsigned short)cm->data.bytes[i*3+2]); } } } len += nColours * 3 * 2; - if (rfbWriteExact(cl, buf, len) < 0) { + if (rfbWriteExact(cl, wbuf, len) < 0) { rfbLogPerror("rfbSendSetColourMapEntries: write"); rfbCloseClient(cl); + if (wbuf != buf) free(wbuf); return FALSE; } rfbStatRecordMessageSent(cl, rfbSetColourMapEntries, len, len); + if (wbuf != buf) free(wbuf); return TRUE; } diff -Nru LibVNCServer-0.9.1/libvncserver/scale.c x11vnc-0.9.5/libvncserver/scale.c --- LibVNCServer-0.9.1/libvncserver/scale.c 2006-05-15 07:37:39.000000000 +0200 +++ x11vnc-0.9.5/libvncserver/scale.c 2008-01-29 12:50:16.000000000 +0100 @@ -151,6 +151,10 @@ h1 = h0; rfbScaledCorrection(screen, ptr, &x1, &y1, &w1, &h1, "rfbScaledScreenUpdateRect"); + x0 = ScaleX(ptr, screen, x1); + y0 = ScaleY(ptr, screen, y1); + w0 = ScaleX(ptr, screen, w1); + h0 = ScaleY(ptr, screen, h1); bitsPerPixel = screen->bitsPerPixel; bytesPerPixel = bitsPerPixel / 8; @@ -197,8 +201,8 @@ /* Get the totals for rgb from the source grid... */ for (w = 0; w < areaX; w++) { for (v = 0; v < areaY; v++) { - srcptr2 = &srcptr[(((x * areaX) + v) * bytesPerPixel) + - (w * screen->paddedWidthInBytes)]; + srcptr2 = &srcptr[(((x * areaX) + w) * bytesPerPixel) + + (v * screen->paddedWidthInBytes)]; pixel_value = 0; diff -Nru LibVNCServer-0.9.1/libvncserver/stats.c x11vnc-0.9.5/libvncserver/stats.c --- LibVNCServer-0.9.1/libvncserver/stats.c 2006-05-16 21:35:17.000000000 +0200 +++ x11vnc-0.9.5/libvncserver/stats.c 2008-02-01 15:12:07.000000000 +0100 @@ -103,6 +103,7 @@ case rfbEncodingZlibHex: snprintf(buf, len, "zlibhex"); break; case rfbEncodingUltra: snprintf(buf, len, "ultra"); break; case rfbEncodingZRLE: snprintf(buf, len, "ZRLE"); break; + case rfbEncodingZYWRLE: snprintf(buf, len, "ZYWRLE"); break; case rfbEncodingCache: snprintf(buf, len, "cache"); break; case rfbEncodingCacheEnable: snprintf(buf, len, "cacheEnable"); break; case rfbEncodingXOR_Zlib: snprintf(buf, len, "xorZlib"); break; diff -Nru LibVNCServer-0.9.1/libvncserver/zrle.c x11vnc-0.9.5/libvncserver/zrle.c --- LibVNCServer-0.9.1/libvncserver/zrle.c 2006-05-15 07:37:39.000000000 +0200 +++ x11vnc-0.9.5/libvncserver/zrle.c 2008-01-30 21:38:51.000000000 +0100 @@ -40,18 +40,50 @@ #define EXTRA_ARGS , rfbClientPtr cl +#define ENDIAN_LITTLE 0 +#define ENDIAN_BIG 1 +#define ENDIAN_NO 2 #define BPP 8 +#define ZYWRLE_ENDIAN ENDIAN_NO +#include +#undef BPP +#define BPP 15 +#undef ZYWRLE_ENDIAN +#define ZYWRLE_ENDIAN ENDIAN_LITTLE +#include +#undef ZYWRLE_ENDIAN +#define ZYWRLE_ENDIAN ENDIAN_BIG #include #undef BPP #define BPP 16 +#undef ZYWRLE_ENDIAN +#define ZYWRLE_ENDIAN ENDIAN_LITTLE +#include +#undef ZYWRLE_ENDIAN +#define ZYWRLE_ENDIAN ENDIAN_BIG #include #undef BPP #define BPP 32 +#undef ZYWRLE_ENDIAN +#define ZYWRLE_ENDIAN ENDIAN_LITTLE +#include +#undef ZYWRLE_ENDIAN +#define ZYWRLE_ENDIAN ENDIAN_BIG #include #define CPIXEL 24A +#undef ZYWRLE_ENDIAN +#define ZYWRLE_ENDIAN ENDIAN_LITTLE +#include +#undef ZYWRLE_ENDIAN +#define ZYWRLE_ENDIAN ENDIAN_BIG #include #undef CPIXEL #define CPIXEL 24B +#undef ZYWRLE_ENDIAN +#define ZYWRLE_ENDIAN ENDIAN_LITTLE +#include +#undef ZYWRLE_ENDIAN +#define ZYWRLE_ENDIAN ENDIAN_BIG #include #undef CPIXEL #undef BPP @@ -64,6 +96,7 @@ * data. */ +/* TODO: put into rfbClient struct */ static char zrleBeforeBuf[rfbZRLETileWidth * rfbZRLETileHeight * 4 + 4]; @@ -80,6 +113,19 @@ rfbZRLEHeader hdr; int i; + if (cl->preferredEncoding == rfbEncodingZYWRLE) { + if (cl->tightQualityLevel < 0) { + cl->zywrleLevel = 1; + } else if (cl->tightQualityLevel < 3) { + cl->zywrleLevel = 3; + } else if (cl->tightQualityLevel < 6) { + cl->zywrleLevel = 2; + } else { + cl->zywrleLevel = 1; + } + } else + cl->zywrleLevel = 0; + if (!cl->zrleData) cl->zrleData = zrleOutStreamNew(); zos = cl->zrleData; @@ -89,11 +135,21 @@ switch (cl->format.bitsPerPixel) { case 8: - zrleEncode8( x, y, w, h, zos, zrleBeforeBuf, cl); + zrleEncode8NE(x, y, w, h, zos, zrleBeforeBuf, cl); break; case 16: - zrleEncode16(x, y, w, h, zos, zrleBeforeBuf, cl); + if (cl->format.greenMax > 0x1F) { + if (cl->format.bigEndian) + zrleEncode16BE(x, y, w, h, zos, zrleBeforeBuf, cl); + else + zrleEncode16LE(x, y, w, h, zos, zrleBeforeBuf, cl); + } else { + if (cl->format.bigEndian) + zrleEncode15BE(x, y, w, h, zos, zrleBeforeBuf, cl); + else + zrleEncode15LE(x, y, w, h, zos, zrleBeforeBuf, cl); + } break; case 32: { @@ -107,18 +163,24 @@ cl->format.blueShift > 7); if ((fitsInLS3Bytes && !cl->format.bigEndian) || - (fitsInMS3Bytes && cl->format.bigEndian)) - { - zrleEncode24A(x, y, w, h, zos, zrleBeforeBuf, cl); + (fitsInMS3Bytes && cl->format.bigEndian)) { + if (cl->format.bigEndian) + zrleEncode24ABE(x, y, w, h, zos, zrleBeforeBuf, cl); + else + zrleEncode24ALE(x, y, w, h, zos, zrleBeforeBuf, cl); } else if ((fitsInLS3Bytes && cl->format.bigEndian) || - (fitsInMS3Bytes && !cl->format.bigEndian)) - { - zrleEncode24B(x, y, w, h, zos, zrleBeforeBuf, cl); - } - else - { - zrleEncode32(x, y, w, h, zos, zrleBeforeBuf, cl); + (fitsInMS3Bytes && !cl->format.bigEndian)) { + if (cl->format.bigEndian) + zrleEncode24BBE(x, y, w, h, zos, zrleBeforeBuf, cl); + else + zrleEncode24BLE(x, y, w, h, zos, zrleBeforeBuf, cl); + } + else { + if (cl->format.bigEndian) + zrleEncode32BE(x, y, w, h, zos, zrleBeforeBuf, cl); + else + zrleEncode32LE(x, y, w, h, zos, zrleBeforeBuf, cl); } } break; @@ -138,7 +200,7 @@ rect.r.y = Swap16IfLE(y); rect.r.w = Swap16IfLE(w); rect.r.h = Swap16IfLE(h); - rect.encoding = Swap32IfLE(rfbEncodingZRLE); + rect.encoding = Swap32IfLE(cl->preferredEncoding); memcpy(cl->updateBuf+cl->ublen, (char *)&rect, sz_rfbFramebufferUpdateRectHeader); diff -Nru LibVNCServer-0.9.1/libvncserver/zrleencodetemplate.c x11vnc-0.9.5/libvncserver/zrleencodetemplate.c --- LibVNCServer-0.9.1/libvncserver/zrleencodetemplate.c 2005-05-15 16:57:54.000000000 +0200 +++ x11vnc-0.9.5/libvncserver/zrleencodetemplate.c 2008-01-30 21:38:51.000000000 +0100 @@ -43,17 +43,37 @@ #define __RFB_CONCAT2E(a,b) __RFB_CONCAT2(a,b) #endif +#ifndef __RFB_CONCAT3E +#define __RFB_CONCAT3(a,b,c) a##b##c +#define __RFB_CONCAT3E(a,b,c) __RFB_CONCAT3(a,b,c) +#endif + +#undef END_FIX +#if ZYWRLE_ENDIAN == ENDIAN_LITTLE +# define END_FIX LE +#elif ZYWRLE_ENDIAN == ENDIAN_BIG +# define END_FIX BE +#else +# define END_FIX NE +#endif + #ifdef CPIXEL #define PIXEL_T __RFB_CONCAT2E(zrle_U,BPP) #define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,CPIXEL) -#define ZRLE_ENCODE __RFB_CONCAT2E(zrleEncode,CPIXEL) -#define ZRLE_ENCODE_TILE __RFB_CONCAT2E(zrleEncodeTile,CPIXEL) +#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,CPIXEL,END_FIX) +#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,CPIXEL,END_FIX) #define BPPOUT 24 +#elif BPP==15 +#define PIXEL_T __RFB_CONCAT2E(zrle_U,16) +#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,16) +#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,BPP,END_FIX) +#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX) +#define BPPOUT 16 #else #define PIXEL_T __RFB_CONCAT2E(zrle_U,BPP) #define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,BPP) -#define ZRLE_ENCODE __RFB_CONCAT2E(zrleEncode,BPP) -#define ZRLE_ENCODE_TILE __RFB_CONCAT2E(zrleEncodeTile,BPP) +#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,BPP,END_FIX) +#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX) #define BPPOUT BPP #endif @@ -68,7 +88,13 @@ #endif /* ZRLE_ONCE */ -void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os); +void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os, + int zywrle_level, int *zywrleBuf); + +#if BPP!=8 +#define ZYWRLE_ENCODE +#include "zywrletemplate.c" +#endif static void ZRLE_ENCODE (int x, int y, int w, int h, zrleOutStream* os, void* buf @@ -85,14 +111,16 @@ GET_IMAGE_INTO_BUF(tx,ty,tw,th,buf); - ZRLE_ENCODE_TILE((PIXEL_T*)buf, tw, th, os); + ZRLE_ENCODE_TILE((PIXEL_T*)buf, tw, th, os, + cl->zywrleLevel, cl->zywrleBuf); } } zrleOutStreamFlush(os); } -void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os) +void ZRLE_ENCODE_TILE(PIXEL_T* data, int w, int h, zrleOutStream* os, + int zywrle_level, int *zywrleBuf) { /* First find the palette and the number of runs */ @@ -144,6 +172,11 @@ estimatedBytes = w * h * (BPPOUT/8); /* start assuming raw */ +#if BPP!=8 + if (zywrle_level > 0 && !(zywrle_level & 0x80)) + estimatedBytes >>= zywrle_level; +#endif + plainRleBytes = ((BPPOUT/8)+1) * (runs + singlePixels); if (plainRleBytes < estimatedBytes) { @@ -253,14 +286,22 @@ /* raw */ -#ifdef CPIXEL - PIXEL_T *ptr; - for (ptr = data; ptr < data+w*h; ptr++) { - zrleOutStreamWRITE_PIXEL(os, *ptr); +#if BPP!=8 + if (zywrle_level > 0 && !(zywrle_level & 0x80)) { + ZYWRLE_ANALYZE(data, data, w, h, w, zywrle_level, zywrleBuf); + ZRLE_ENCODE_TILE(data, w, h, os, zywrle_level | 0x80, zywrleBuf); } + else +#endif + { +#ifdef CPIXEL + PIXEL_T *ptr; + for (ptr = data; ptr < data+w*h; ptr++) + zrleOutStreamWRITE_PIXEL(os, *ptr); #else - zrleOutStreamWriteBytes(os, (zrle_U8 *)data, w*h*(BPP/8)); + zrleOutStreamWriteBytes(os, (zrle_U8 *)data, w*h*(BPP/8)); #endif + } } } } @@ -269,4 +310,5 @@ #undef zrleOutStreamWRITE_PIXEL #undef ZRLE_ENCODE #undef ZRLE_ENCODE_TILE +#undef ZYWRLE_ENCODE_TILE #undef BPPOUT diff -Nru LibVNCServer-0.9.1/libvncserver/zywrletemplate.c x11vnc-0.9.5/libvncserver/zywrletemplate.c --- LibVNCServer-0.9.1/libvncserver/zywrletemplate.c 1970-01-01 01:00:00.000000000 +0100 +++ x11vnc-0.9.5/libvncserver/zywrletemplate.c 2008-02-18 05:10:45.000000000 +0100 @@ -0,0 +1,824 @@ + +/******************************************************************** + * * + * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE. * + * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006 * + * BY Hitachi Systems & Services, Ltd. * + * (Noriaki Yamazaki, Research & Developement Center) * * + * * + ******************************************************************** +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Hitachi Systems & Services, Ltd. nor +the names of its contributors may be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************/ + +/* Change Log: + V0.02 : 2008/02/04 : Fix mis encode/decode when width != scanline + (Thanks Johannes Schindelin, author of LibVNC + Server/Client) + V0.01 : 2007/02/06 : Initial release +*/ + +/* #define ZYWRLE_ENCODE */ +/* #define ZYWRLE_DECODE */ +#define ZYWRLE_QUANTIZE + +/* +[References] + PLHarr: + Senecal, J. G., P. Lindstrom, M. A. Duchaineau, and K. I. Joy, "An Improved N-Bit to N-Bit Reversible Haar-Like Transform," Pacific Graphics 2004, October 2004, pp. 371-380. + EZW: + Shapiro, JM: Embedded Image Coding Using Zerotrees of Wavelet Coefficients, IEEE Trans. Signal. Process., Vol.41, pp.3445-3462 (1993). +*/ + + +/* Template Macro stuffs. */ +#undef ZYWRLE_ANALYZE +#undef ZYWRLE_SYNTHESIZE +#define ZYWRLE_ANALYZE __RFB_CONCAT3E(zywrleAnalyze,BPP,END_FIX) +#define ZYWRLE_SYNTHESIZE __RFB_CONCAT3E(zywrleSynthesize,BPP,END_FIX) + +#define ZYWRLE_RGBYUV __RFB_CONCAT3E(zywrleRGBYUV,BPP,END_FIX) +#define ZYWRLE_YUVRGB __RFB_CONCAT3E(zywrleYUVRGB,BPP,END_FIX) +#define ZYWRLE_YMASK __RFB_CONCAT2E(ZYWRLE_YMASK,BPP) +#define ZYWRLE_UVMASK __RFB_CONCAT2E(ZYWRLE_UVMASK,BPP) +#define ZYWRLE_LOAD_PIXEL __RFB_CONCAT2E(ZYWRLE_LOAD_PIXEL,BPP) +#define ZYWRLE_SAVE_PIXEL __RFB_CONCAT2E(ZYWRLE_SAVE_PIXEL,BPP) + +/* Packing/Unpacking pixel stuffs. + Endian conversion stuffs. */ +#undef S_0 +#undef S_1 +#undef L_0 +#undef L_1 +#undef L_2 +#if ZYWRLE_ENDIAN == ENDIAN_BIG +# define S_0 1 +# define S_1 0 +# define L_0 3 +# define L_1 2 +# define L_2 1 +#else +# define S_0 0 +# define S_1 1 +# define L_0 0 +# define L_1 1 +# define L_2 2 +#endif + +/* Load/Save pixel stuffs. */ +#define ZYWRLE_YMASK15 0xFFFFFFF8 +#define ZYWRLE_UVMASK15 0xFFFFFFF8 +#define ZYWRLE_LOAD_PIXEL15(pSrc,R,G,B) { \ + R = (((unsigned char*)pSrc)[S_1]<< 1)& 0xF8; \ + G = ((((unsigned char*)pSrc)[S_1]<< 6)|(((unsigned char*)pSrc)[S_0]>> 2))& 0xF8; \ + B = (((unsigned char*)pSrc)[S_0]<< 3)& 0xF8; \ +} +#define ZYWRLE_SAVE_PIXEL15(pDst,R,G,B) { \ + R &= 0xF8; \ + G &= 0xF8; \ + B &= 0xF8; \ + ((unsigned char*)pDst)[S_1] = (unsigned char)( (R>>1)|(G>>6) ); \ + ((unsigned char*)pDst)[S_0] = (unsigned char)(((B>>3)|(G<<2))& 0xFF); \ +} +#define ZYWRLE_YMASK16 0xFFFFFFFC +#define ZYWRLE_UVMASK16 0xFFFFFFF8 +#define ZYWRLE_LOAD_PIXEL16(pSrc,R,G,B) { \ + R = ((unsigned char*)pSrc)[S_1] & 0xF8; \ + G = ((((unsigned char*)pSrc)[S_1]<< 5)|(((unsigned char*)pSrc)[S_0]>> 3))& 0xFC; \ + B = (((unsigned char*)pSrc)[S_0]<< 3)& 0xF8; \ +} +#define ZYWRLE_SAVE_PIXEL16(pDst,R,G,B) { \ + R &= 0xF8; \ + G &= 0xFC; \ + B &= 0xF8; \ + ((unsigned char*)pDst)[S_1] = (unsigned char)( R |(G>>5) ); \ + ((unsigned char*)pDst)[S_0] = (unsigned char)(((B>>3)|(G<<3))& 0xFF); \ +} +#define ZYWRLE_YMASK32 0xFFFFFFFF +#define ZYWRLE_UVMASK32 0xFFFFFFFF +#define ZYWRLE_LOAD_PIXEL32(pSrc,R,G,B) { \ + R = ((unsigned char*)pSrc)[L_2]; \ + G = ((unsigned char*)pSrc)[L_1]; \ + B = ((unsigned char*)pSrc)[L_0]; \ +} +#define ZYWRLE_SAVE_PIXEL32(pDst,R,G,B) { \ + ((unsigned char*)pDst)[L_2] = (unsigned char)R; \ + ((unsigned char*)pDst)[L_1] = (unsigned char)G; \ + ((unsigned char*)pDst)[L_0] = (unsigned char)B; \ +} + +#ifndef ZYWRLE_ONCE +#define ZYWRLE_ONCE + +#ifdef WIN32 +#define InlineX __inline +#else +#define InlineX inline +#endif + +#ifdef ZYWRLE_ENCODE +/* Tables for Coefficients filtering. */ +# ifndef ZYWRLE_QUANTIZE +/* Type A:lower bit omitting of EZW style. */ +const static unsigned int zywrleParam[3][3]={ + {0x0000F000,0x00000000,0x00000000}, + {0x0000C000,0x00F0F0F0,0x00000000}, + {0x0000C000,0x00C0C0C0,0x00F0F0F0}, +/* {0x0000FF00,0x00000000,0x00000000}, + {0x0000FF00,0x00FFFFFF,0x00000000}, + {0x0000FF00,0x00FFFFFF,0x00FFFFFF}, */ +}; +# else +/* Type B:Non liner quantization filter. */ +static const signed char zywrleConv[4][256]={ +{ /* bi=5, bo=5 r=0.0:PSNR=24.849 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}, +{ /* bi=5, bo=5 r=2.0:PSNR=74.031 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 64, 64, 64, 64, + 64, 64, 64, 64, 72, 72, 72, 72, + 72, 72, 72, 72, 80, 80, 80, 80, + 80, 80, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 96, 96, + 96, 96, 96, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 0, -120, -120, -120, -120, -120, -120, -120, + -120, -120, -120, -112, -112, -112, -112, -112, + -112, -112, -112, -112, -104, -104, -104, -104, + -104, -104, -104, -104, -104, -104, -96, -96, + -96, -96, -96, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -80, + -80, -80, -80, -80, -80, -72, -72, -72, + -72, -72, -72, -72, -72, -64, -64, -64, + -64, -64, -64, -64, -64, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, + -48, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}, +{ /* bi=5, bo=4 r=2.0:PSNR=64.441 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 0, -120, -120, -120, -120, -120, -120, -120, + -120, -120, -120, -120, -120, -112, -112, -112, + -112, -112, -112, -112, -112, -112, -104, -104, + -104, -104, -104, -104, -104, -104, -104, -104, + -104, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, + -80, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, + -64, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, + -48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}, +{ /* bi=5, bo=2 r=2.0:PSNR=43.175 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 0, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +} +}; +const static signed char* zywrleParam[3][3][3]={ + {{zywrleConv[0],zywrleConv[2],zywrleConv[0]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]}}, + {{zywrleConv[0],zywrleConv[3],zywrleConv[0]},{zywrleConv[1],zywrleConv[1],zywrleConv[1]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]}}, + {{zywrleConv[0],zywrleConv[3],zywrleConv[0]},{zywrleConv[2],zywrleConv[2],zywrleConv[2]},{zywrleConv[1],zywrleConv[1],zywrleConv[1]}}, +}; +# endif +#endif + +static InlineX void Harr(signed char* pX0, signed char* pX1) +{ + /* Piecewise-Linear Harr(PLHarr) */ + int X0 = (int)*pX0, X1 = (int)*pX1; + int orgX0 = X0, orgX1 = X1; + if ((X0 ^ X1) & 0x80) { + /* differ sign */ + X1 += X0; + if (((X1^orgX1)&0x80)==0) { + /* |X1| > |X0| */ + X0 -= X1; /* H = -B */ + } + } else { + /* same sign */ + X0 -= X1; + if (((X0 ^ orgX0) & 0x80) == 0) { + /* |X0| > |X1| */ + X1 += X0; /* L = A */ + } + } + *pX0 = (signed char)X1; + *pX1 = (signed char)X0; +} +/* + 1D-Wavelet transform. + + In coefficients array, the famous 'pyramid' decomposition is well used. + + 1D Model: + |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0 + |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1 + + But this method needs line buffer because H/L is different position from X0/X1. + So, I used 'interleave' decomposition instead of it. + + 1D Model: + |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0 + |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1 + + In this method, H/L and X0/X1 is always same position. + This lead us to more speed and less memory. + Of cause, the result of both method is quite same + because it's only difference that coefficient position. +*/ +static InlineX void WaveletLevel(int* data, int size, int l, int SkipPixel) +{ + int s, ofs; + signed char* pX0; + signed char* end; + + pX0 = (signed char*)data; + s = (8<>(l+1))*s; + s -= 2; + ofs = (4<>1; + if (r & 0x02) + pH += (s>>1)*width; + for (y = 0; y < height / s; y++) { + for (x = 0; x < width / s; x++) { + /* + these are same following code. + pH[x] = pH[x] / (~pM[x]+1) * (~pM[x]+1); + ( round pH[x] with pM[x] bit ) + '&' operator isn't 'round' but is 'floor'. + So, we must offset when pH[x] is negative. + */ + if (((signed char*)pH)[0] & 0x80) + ((signed char*)pH)[0] += ~((signed char*)pM)[0]; + if (((signed char*)pH)[1] & 0x80) + ((signed char*)pH)[1] += ~((signed char*)pM)[1]; + if (((signed char*)pH)[2] & 0x80) + ((signed char*)pH)[2] += ~((signed char*)pM)[2]; + *pH &= *pM; + pH += s; + } + pH += (s-1)*width; + } + } +} +# else +/* + Type B:Non liner quantization filter. + + Coefficients have Gaussian curve and smaller value which is + large part of coefficients isn't more important than larger value. + So, I use filter of Non liner quantize/dequantize table. + In general, Non liner quantize formula is explained as following. + + y=f(x) = sign(x)*round( ((abs(x)/(2^7))^ r )* 2^(bo-1) )*2^(8-bo) + x=f-1(y) = sign(y)*round( ((abs(y)/(2^7))^(1/r))* 2^(bi-1) )*2^(8-bi) + ( r:power coefficient bi:effective MSB in input bo:effective MSB in output ) + + r < 1.0 : Smaller value is more important than larger value. + r > 1.0 : Larger value is more important than smaller value. + r = 1.0 : Liner quantization which is same with EZW style. + + r = 0.75 is famous non liner quantization used in MP3 audio codec. + In contrast to audio data, larger value is important in wavelet coefficients. + So, I select r = 2.0 table( quantize is x^2, dequantize sqrt(x) ). + + As compared with EZW style liner quantization, this filter tended to be + more sharp edge and be more compression rate but be more blocking noise and be less quality. + Especially, the surface of graphic objects has distinguishable noise in middle quality mode. + + We need only quantized-dequantized(filtered) value rather than quantized value itself + because all values are packed or palette-lized in later ZRLE section. + This lead us not to need to modify client decoder when we change + the filtering procedure in future. + Client only decodes coefficients given by encoder. +*/ +static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int level, int l) +{ + int r, s; + int x, y; + int* pH; + const signed char** pM; + + pM = zywrleParam[level-1][l]; + s = 2<>1; + if (r & 0x02) + pH += (s>>1)*width; + for (y = 0; y < height / s; y++) { + for (x = 0; x < width / s; x++) { + ((signed char*)pH)[0] = pM[0][((unsigned char*)pH)[0]]; + ((signed char*)pH)[1] = pM[1][((unsigned char*)pH)[1]]; + ((signed char*)pH)[2] = pM[2][((unsigned char*)pH)[2]]; + pH += s; + } + pH += (s-1)*width; + } + } +} +# endif + +static InlineX void Wavelet(int* pBuf, int width, int height, int level) +{ + int l, s; + int* pTop; + int* pEnd; + + for (l = 0; l < level; l++) { + pTop = pBuf; + pEnd = pBuf+height*width; + s = width<= 0; l--) { + pTop = pBuf; + pEnd = pBuf+width; + s = 1< YUV conversion stuffs. + YUV coversion is explained as following formula in strict meaning: + Y = 0.299R + 0.587G + 0.114B ( 0<=Y<=255) + U = -0.169R - 0.331G + 0.500B (-128<=U<=127) + V = 0.500R - 0.419G - 0.081B (-128<=V<=127) + + I use simple conversion RCT(reversible color transform) which is described + in JPEG-2000 specification. + Y = (R + 2G + B)/4 ( 0<=Y<=255) + U = B-G (-256<=U<=255) + V = R-G (-256<=V<=255) +*/ +#define ROUND(x) (((x)<0)?0:(((x)>255)?255:(x))) + /* RCT is N-bit RGB to N-bit Y and N+1-bit UV. + For make Same N-bit, UV is lossy. + More exact PLHarr, we reduce to odd range(-127<=x<=127). */ +#define ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ymask,uvmask) { \ + Y = (R+(G<<1)+B)>>2; \ + U = B-G; \ + V = R-G; \ + Y -= 128; \ + U >>= 1; \ + V >>= 1; \ + Y &= ymask; \ + U &= uvmask; \ + V &= uvmask; \ + if (Y == -128) \ + Y += (0xFFFFFFFF-ymask+1); \ + if (U == -128) \ + U += (0xFFFFFFFF-uvmask+1); \ + if (V == -128) \ + V += (0xFFFFFFFF-uvmask+1); \ +} +#define ZYWRLE_YUVRGB1(R,G,B,Y,U,V) { \ + Y += 128; \ + U <<= 1; \ + V <<= 1; \ + G = Y-((U+V)>>2); \ + B = U+G; \ + R = V+G; \ + G = ROUND(G); \ + B = ROUND(B); \ + R = ROUND(R); \ +} + +/* + coefficient packing/unpacking stuffs. + Wavelet transform makes 4 sub coefficient image from 1 original image. + + model with pyramid decomposition: + +------+------+ + | | | + | L | Hx | + | | | + +------+------+ + | | | + | H | Hxy | + | | | + +------+------+ + + So, we must transfer each sub images individually in strict meaning. + But at least ZRLE meaning, following one decompositon image is same as + avobe individual sub image. I use this format. + (Strictly saying, transfer order is reverse(Hxy->Hy->Hx->L) + for simplified procedure for any wavelet level.) + + +------+------+ + | L | + +------+------+ + | Hx | + +------+------+ + | Hy | + +------+------+ + | Hxy | + +------+------+ +*/ +#define INC_PTR(data) \ + data++; \ + if( data-pData >= (w+uw) ){ \ + data += scanline-(w+uw); \ + pData = data; \ + } + +#define ZYWRLE_TRANSFER_COEFF(pBuf,data,r,w,h,scanline,level,TRANS) \ + pH = pBuf; \ + s = 2<>1; \ + if (r & 0x02) \ + pH += (s>>1)*w; \ + pEnd = pH+h*w; \ + while (pH < pEnd) { \ + pLine = pH+w; \ + while (pH < pLine) { \ + TRANS \ + INC_PTR(data) \ + pH += s; \ + } \ + pH += (s-1)*w; \ + } + +#define ZYWRLE_PACK_COEFF(pBuf,data,r,width,height,scanline,level) \ + ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,scanline,level,ZYWRLE_LOAD_COEFF(pH,R,G,B);ZYWRLE_SAVE_PIXEL(data,R,G,B);) + +#define ZYWRLE_UNPACK_COEFF(pBuf,data,r,width,height,scanline,level) \ + ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,scanline,level,ZYWRLE_LOAD_PIXEL(data,R,G,B);ZYWRLE_SAVE_COEFF(pH,R,G,B);) + +#define ZYWRLE_SAVE_UNALIGN(data,TRANS) \ + pTop = pBuf+w*h; \ + pEnd = pBuf + (w+uw)*(h+uh); \ + while (pTop < pEnd) { \ + TRANS \ + INC_PTR(data) \ + pTop++; \ + } + +#define ZYWRLE_LOAD_UNALIGN(data,TRANS) \ + pTop = pBuf+w*h; \ + if (uw) { \ + pData= data + w; \ + pEnd = (int*)(pData+ h*scanline); \ + while (pData < (PIXEL_T*)pEnd) { \ + pLine = (int*)(pData + uw); \ + while (pData < (PIXEL_T*)pLine) { \ + TRANS \ + pData++; \ + pTop++; \ + } \ + pData += scanline-uw; \ + } \ + } \ + if (uh) { \ + pData= data + h*scanline; \ + pEnd = (int*)(pData+ uh*scanline); \ + while (pData < (PIXEL_T*)pEnd) { \ + pLine = (int*)(pData + w); \ + while (pData < (PIXEL_T*)pLine) { \ + TRANS \ + pData++; \ + pTop++; \ + } \ + pData += scanline-w; \ + } \ + } \ + if (uw && uh) { \ + pData= data + w+ h*scanline; \ + pEnd = (int*)(pData+ uh*scanline); \ + while (pData < (PIXEL_T*)pEnd) { \ + pLine = (int*)(pData + uw); \ + while (pData < (PIXEL_T*)pLine) { \ + TRANS \ + pData++; \ + pTop++; \ + } \ + pData += scanline-uw; \ + } \ + } + +static InlineX void zywrleCalcSize(int* pW, int* pH, int level) +{ + *pW &= ~((1< header file. */ -#ifndef LIBVNCSERVER_HAVE_DLFCN_H -#define LIBVNCSERVER_HAVE_DLFCN_H 1 -#endif +/* #undef LIBVNCSERVER_HAVE_DLFCN_H */ /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ /* #undef LIBVNCSERVER_HAVE_DOPRNT */ /* DPMS extension build environment present */ -/* #undef LIBVNCSERVER_HAVE_DPMS */ +#ifndef LIBVNCSERVER_HAVE_DPMS +#define LIBVNCSERVER_HAVE_DPMS 1 +#endif /* FBPM extension build environment present */ /* #undef LIBVNCSERVER_HAVE_FBPM */ @@ -57,7 +57,9 @@ #endif /* Define to 1 if you have the `geteuid' function. */ -/* #undef LIBVNCSERVER_HAVE_GETEUID */ +#ifndef LIBVNCSERVER_HAVE_GETEUID +#define LIBVNCSERVER_HAVE_GETEUID 1 +#endif /* Define to 1 if you have the `gethostbyname' function. */ #ifndef LIBVNCSERVER_HAVE_GETHOSTBYNAME @@ -70,13 +72,19 @@ #endif /* Define to 1 if you have the `getpwnam' function. */ -/* #undef LIBVNCSERVER_HAVE_GETPWNAM */ +#ifndef LIBVNCSERVER_HAVE_GETPWNAM +#define LIBVNCSERVER_HAVE_GETPWNAM 1 +#endif /* Define to 1 if you have the `getpwuid' function. */ -/* #undef LIBVNCSERVER_HAVE_GETPWUID */ +#ifndef LIBVNCSERVER_HAVE_GETPWUID +#define LIBVNCSERVER_HAVE_GETPWUID 1 +#endif /* Define to 1 if you have the `getspnam' function. */ -/* #undef LIBVNCSERVER_HAVE_GETSPNAM */ +#ifndef LIBVNCSERVER_HAVE_GETSPNAM +#define LIBVNCSERVER_HAVE_GETSPNAM 1 +#endif /* Define to 1 if you have the `gettimeofday' function. */ #ifndef LIBVNCSERVER_HAVE_GETTIMEOFDAY @@ -84,10 +92,14 @@ #endif /* Define to 1 if you have the `getuid' function. */ -/* #undef LIBVNCSERVER_HAVE_GETUID */ +#ifndef LIBVNCSERVER_HAVE_GETUID +#define LIBVNCSERVER_HAVE_GETUID 1 +#endif /* Define to 1 if you have the `grantpt' function. */ -/* #undef LIBVNCSERVER_HAVE_GRANTPT */ +#ifndef LIBVNCSERVER_HAVE_GRANTPT +#define LIBVNCSERVER_HAVE_GRANTPT 1 +#endif /* Define to 1 if you have the `inet_ntoa' function. */ #ifndef LIBVNCSERVER_HAVE_INET_NTOA @@ -95,7 +107,9 @@ #endif /* Define to 1 if you have the `initgroups' function. */ -/* #undef LIBVNCSERVER_HAVE_INITGROUPS */ +#ifndef LIBVNCSERVER_HAVE_INITGROUPS +#define LIBVNCSERVER_HAVE_INITGROUPS 1 +#endif /* Define to 1 if you have the header file. */ #ifndef LIBVNCSERVER_HAVE_INTTYPES_H @@ -106,10 +120,14 @@ /* #undef LIBVNCSERVER_HAVE_IRIX_XREADDISPLAY */ /* libcrypt library present */ -/* #undef LIBVNCSERVER_HAVE_LIBCRYPT */ +#ifndef LIBVNCSERVER_HAVE_LIBCRYPT +#define LIBVNCSERVER_HAVE_LIBCRYPT 1 +#endif /* openssl libcrypto library present */ -/* #undef LIBVNCSERVER_HAVE_LIBCRYPTO */ +#ifndef LIBVNCSERVER_HAVE_LIBCRYPTO +#define LIBVNCSERVER_HAVE_LIBCRYPTO 1 +#endif /* Define to 1 if you have the `cygipc' library (-lcygipc). */ /* #undef LIBVNCSERVER_HAVE_LIBCYGIPC */ @@ -133,7 +151,9 @@ /* #undef LIBVNCSERVER_HAVE_LIBSOCKET */ /* openssl libssl library present */ -/* #undef LIBVNCSERVER_HAVE_LIBSSL */ +#ifndef LIBVNCSERVER_HAVE_LIBSSL +#define LIBVNCSERVER_HAVE_LIBSSL 1 +#endif /* XDAMAGE extension build environment present */ /* #undef LIBVNCSERVER_HAVE_LIBXDAMAGE */ @@ -142,10 +162,14 @@ /* #undef LIBVNCSERVER_HAVE_LIBXFIXES */ /* XINERAMA extension build environment present */ -/* #undef LIBVNCSERVER_HAVE_LIBXINERAMA */ +#ifndef LIBVNCSERVER_HAVE_LIBXINERAMA +#define LIBVNCSERVER_HAVE_LIBXINERAMA 1 +#endif /* XRANDR extension build environment present */ -/* #undef LIBVNCSERVER_HAVE_LIBXRANDR */ +#ifndef LIBVNCSERVER_HAVE_LIBXRANDR +#define LIBVNCSERVER_HAVE_LIBXRANDR 1 +#endif /* DEC-XTRAP extension build environment present */ /* #undef LIBVNCSERVER_HAVE_LIBXTRAP */ @@ -156,19 +180,29 @@ #endif /* linux fb device build environment present */ -/* #undef LIBVNCSERVER_HAVE_LINUX_FB_H */ +#ifndef LIBVNCSERVER_HAVE_LINUX_FB_H +#define LIBVNCSERVER_HAVE_LINUX_FB_H 1 +#endif /* linux/input.h present */ -/* #undef LIBVNCSERVER_HAVE_LINUX_INPUT_H */ +#ifndef LIBVNCSERVER_HAVE_LINUX_INPUT_H +#define LIBVNCSERVER_HAVE_LINUX_INPUT_H 1 +#endif /* linux uinput device build environment present */ -/* #undef LIBVNCSERVER_HAVE_LINUX_UINPUT_H */ +#ifndef LIBVNCSERVER_HAVE_LINUX_UINPUT_H +#define LIBVNCSERVER_HAVE_LINUX_UINPUT_H 1 +#endif /* video4linux build environment present */ -/* #undef LIBVNCSERVER_HAVE_LINUX_VIDEODEV_H */ +#ifndef LIBVNCSERVER_HAVE_LINUX_VIDEODEV_H +#define LIBVNCSERVER_HAVE_LINUX_VIDEODEV_H 1 +#endif /* build MacOS X native display support */ -/* #undef LIBVNCSERVER_HAVE_MACOSX_NATIVE_DISPLAY */ +#ifndef LIBVNCSERVER_HAVE_MACOSX_NATIVE_DISPLAY +#define LIBVNCSERVER_HAVE_MACOSX_NATIVE_DISPLAY 1 +#endif /* Define to 1 if you have the `memmove' function. */ #ifndef LIBVNCSERVER_HAVE_MEMMOVE @@ -206,10 +240,14 @@ #endif /* Define to 1 if you have the header file. */ -/* #undef LIBVNCSERVER_HAVE_PWD_H */ +#ifndef LIBVNCSERVER_HAVE_PWD_H +#define LIBVNCSERVER_HAVE_PWD_H 1 +#endif /* RECORD extension build environment present */ -/* #undef LIBVNCSERVER_HAVE_RECORD */ +#ifndef LIBVNCSERVER_HAVE_RECORD +#define LIBVNCSERVER_HAVE_RECORD 1 +#endif /* Define to 1 if you have the `select' function. */ #ifndef LIBVNCSERVER_HAVE_SELECT @@ -217,25 +255,39 @@ #endif /* Define to 1 if you have the `setegid' function. */ -/* #undef LIBVNCSERVER_HAVE_SETEGID */ +#ifndef LIBVNCSERVER_HAVE_SETEGID +#define LIBVNCSERVER_HAVE_SETEGID 1 +#endif /* Define to 1 if you have the `seteuid' function. */ -/* #undef LIBVNCSERVER_HAVE_SETEUID */ +#ifndef LIBVNCSERVER_HAVE_SETEUID +#define LIBVNCSERVER_HAVE_SETEUID 1 +#endif /* Define to 1 if you have the `setgid' function. */ -/* #undef LIBVNCSERVER_HAVE_SETGID */ +#ifndef LIBVNCSERVER_HAVE_SETGID +#define LIBVNCSERVER_HAVE_SETGID 1 +#endif /* Define to 1 if you have the `setpgrp' function. */ -/* #undef LIBVNCSERVER_HAVE_SETPGRP */ +#ifndef LIBVNCSERVER_HAVE_SETPGRP +#define LIBVNCSERVER_HAVE_SETPGRP 1 +#endif /* Define to 1 if you have the `setsid' function. */ -/* #undef LIBVNCSERVER_HAVE_SETSID */ +#ifndef LIBVNCSERVER_HAVE_SETSID +#define LIBVNCSERVER_HAVE_SETSID 1 +#endif /* Define to 1 if you have the `setuid' function. */ -/* #undef LIBVNCSERVER_HAVE_SETUID */ +#ifndef LIBVNCSERVER_HAVE_SETUID +#define LIBVNCSERVER_HAVE_SETUID 1 +#endif /* Define to 1 if you have the `setutxent' function. */ -/* #undef LIBVNCSERVER_HAVE_SETUTXENT */ +#ifndef LIBVNCSERVER_HAVE_SETUTXENT +#define LIBVNCSERVER_HAVE_SETUTXENT 1 +#endif /* Define to 1 if you have the `socket' function. */ #ifndef LIBVNCSERVER_HAVE_SOCKET @@ -308,7 +360,9 @@ /* #undef LIBVNCSERVER_HAVE_SYSTEM_LIBVNCSERVER */ /* Define to 1 if you have the header file. */ -/* #undef LIBVNCSERVER_HAVE_SYS_IOCTL_H */ +#ifndef LIBVNCSERVER_HAVE_SYS_IOCTL_H +#define LIBVNCSERVER_HAVE_SYS_IOCTL_H 1 +#endif /* Define to 1 if you have the header file. */ #ifndef LIBVNCSERVER_HAVE_SYS_SOCKET_H @@ -321,7 +375,9 @@ #endif /* Define to 1 if you have the header file. */ -/* #undef LIBVNCSERVER_HAVE_SYS_STROPTS_H */ +#ifndef LIBVNCSERVER_HAVE_SYS_STROPTS_H +#define LIBVNCSERVER_HAVE_SYS_STROPTS_H 1 +#endif /* Define to 1 if you have the header file. */ #ifndef LIBVNCSERVER_HAVE_SYS_TIMEB_H @@ -344,7 +400,9 @@ #endif /* Define to 1 if you have the header file. */ -/* #undef LIBVNCSERVER_HAVE_TERMIOS_H */ +#ifndef LIBVNCSERVER_HAVE_TERMIOS_H +#define LIBVNCSERVER_HAVE_TERMIOS_H 1 +#endif /* Define to 1 if you have the header file. */ #ifndef LIBVNCSERVER_HAVE_UNISTD_H @@ -352,7 +410,9 @@ #endif /* Define to 1 if you have the header file. */ -/* #undef LIBVNCSERVER_HAVE_UTMPX_H */ +#ifndef LIBVNCSERVER_HAVE_UTMPX_H +#define LIBVNCSERVER_HAVE_UTMPX_H 1 +#endif /* Define to 1 if you have the `vfork' function. */ #ifndef LIBVNCSERVER_HAVE_VFORK @@ -368,7 +428,9 @@ #endif /* Define to 1 if you have the `waitpid' function. */ -/* #undef LIBVNCSERVER_HAVE_WAITPID */ +#ifndef LIBVNCSERVER_HAVE_WAITPID +#define LIBVNCSERVER_HAVE_WAITPID 1 +#endif /* Define to 1 if `fork' works. */ #ifndef LIBVNCSERVER_HAVE_WORKING_FORK @@ -385,17 +447,30 @@ #define LIBVNCSERVER_HAVE_X11 1 #endif +/* open ssl X509_print_ex_fp available */ +#ifndef LIBVNCSERVER_HAVE_X509_PRINT_EX_FP +#define LIBVNCSERVER_HAVE_X509_PRINT_EX_FP 1 +#endif + /* XKEYBOARD extension build environment present */ -/* #undef LIBVNCSERVER_HAVE_XKEYBOARD */ +#ifndef LIBVNCSERVER_HAVE_XKEYBOARD +#define LIBVNCSERVER_HAVE_XKEYBOARD 1 +#endif /* MIT-SHM extension build environment present */ -/* #undef LIBVNCSERVER_HAVE_XSHM */ +#ifndef LIBVNCSERVER_HAVE_XSHM +#define LIBVNCSERVER_HAVE_XSHM 1 +#endif /* XTEST extension build environment present */ -/* #undef LIBVNCSERVER_HAVE_XTEST */ +#ifndef LIBVNCSERVER_HAVE_XTEST +#define LIBVNCSERVER_HAVE_XTEST 1 +#endif /* XTEST extension has XTestGrabControl */ -/* #undef LIBVNCSERVER_HAVE_XTESTGRABCONTROL */ +#ifndef LIBVNCSERVER_HAVE_XTESTGRABCONTROL +#define LIBVNCSERVER_HAVE_XTESTGRABCONTROL 1 +#endif /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */ @@ -408,7 +483,7 @@ /* Name of package */ #ifndef LIBVNCSERVER_PACKAGE -#define LIBVNCSERVER_PACKAGE "LibVNCServer" +#define LIBVNCSERVER_PACKAGE "x11vnc" #endif /* Define to the address where bug reports for this package should be sent. */ @@ -418,22 +493,22 @@ /* Define to the full name of this package. */ #ifndef LIBVNCSERVER_PACKAGE_NAME -#define LIBVNCSERVER_PACKAGE_NAME "LibVNCServer" +#define LIBVNCSERVER_PACKAGE_NAME "x11vnc" #endif /* Define to the full name and version of this package. */ #ifndef LIBVNCSERVER_PACKAGE_STRING -#define LIBVNCSERVER_PACKAGE_STRING "LibVNCServer 0.9.1" +#define LIBVNCSERVER_PACKAGE_STRING "x11vnc 0.9.5" #endif /* Define to the one symbol short name of this package. */ #ifndef LIBVNCSERVER_PACKAGE_TARNAME -#define LIBVNCSERVER_PACKAGE_TARNAME "libvncserver" +#define LIBVNCSERVER_PACKAGE_TARNAME "x11vnc" #endif /* Define to the version of this package. */ #ifndef LIBVNCSERVER_PACKAGE_VERSION -#define LIBVNCSERVER_PACKAGE_VERSION "0.9.1" +#define LIBVNCSERVER_PACKAGE_VERSION "0.9.5" #endif /* The number of bytes in type char */ @@ -463,7 +538,7 @@ /* Version number of package */ #ifndef LIBVNCSERVER_VERSION -#define LIBVNCSERVER_VERSION "0.9.1" +#define LIBVNCSERVER_VERSION "0.9.5" #endif /* Disable TightVNCFileTransfer protocol */ diff -Nru LibVNCServer-0.9.1/rfb/rfb.h x11vnc-0.9.5/rfb/rfb.h --- LibVNCServer-0.9.1/rfb/rfb.h 2007-04-06 10:58:30.000000000 +0200 +++ x11vnc-0.9.5/rfb/rfb.h 2008-01-31 12:52:28.000000000 +0100 @@ -525,6 +525,8 @@ struct z_stream_s compStream; rfbBool compStreamInited; uint32_t zlibCompressLevel; + /* the quality level is also used by ZYWRLE */ + int tightQualityLevel; #ifdef LIBVNCSERVER_HAVE_LIBJPEG /* tight encoding -- preserve zlib streams' state for each client */ @@ -532,7 +534,6 @@ rfbBool zsActive[4]; int zsLevel[4]; int tightCompressLevel; - int tightQualityLevel; #endif #endif @@ -579,6 +580,8 @@ #ifdef LIBVNCSERVER_HAVE_LIBZ void* zrleData; + int zywrleLevel; + int zywrleBuf[rfbZRLETileWidth * rfbZRLETileHeight]; #endif /* if progressive updating is on, this variable holds the current diff -Nru LibVNCServer-0.9.1/rfb/rfbproto.h x11vnc-0.9.5/rfb/rfbproto.h --- LibVNCServer-0.9.1/rfb/rfbproto.h 2006-12-16 16:06:31.000000000 +0100 +++ x11vnc-0.9.5/rfb/rfbproto.h 2008-01-29 12:50:17.000000000 +0100 @@ -403,6 +403,7 @@ #define rfbEncodingZlibHex 8 #define rfbEncodingUltra 9 #define rfbEncodingZRLE 16 +#define rfbEncodingZYWRLE 17 /* Cache & XOR-Zlib - rdv@2002 */ #define rfbEncodingCache 0xFFFF0000