diff -rcN ../LibVNCServer-0.8.2.org/libvncserver/rfbserver.c ./libvncserver/rfbserver.c *** ../LibVNCServer-0.8.2.org/libvncserver/rfbserver.c Wed Aug 02 14:42:02 2006 --- ./libvncserver/rfbserver.c Thu Aug 03 09:26:33 2006 *************** *** 952,957 **** --- 952,958 ---- #endif #ifdef LIBVNCSERVER_HAVE_LIBZ rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingZRLE); + rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingZYWRLE); #endif rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingUltra); rfbSendSupporteddEncodings_SendEncoding(cl, rfbEncodingUltraZip); *************** *** 1863,1868 **** --- 1864,1870 ---- #ifdef LIBVNCSERVER_HAVE_LIBZ case rfbEncodingZlib: case rfbEncodingZRLE: + case rfbEncodingZYWRLE: #ifdef LIBVNCSERVER_HAVE_LIBJPEG case rfbEncodingTight: #endif *************** *** 2761,2766 **** --- 2763,2769 ---- #endif #ifdef LIBVNCSERVER_HAVE_LIBZ case rfbEncodingZRLE: + case rfbEncodingZYWRLE: if (!rfbSendRectEncodingZRLE(cl, x, y, w, h)) goto updateFailed; break; diff -rcN ../LibVNCServer-0.8.2.org/libvncserver/scale.c ./libvncserver/scale.c *** ../LibVNCServer-0.8.2.org/libvncserver/scale.c Wed Aug 02 14:42:03 2006 --- ./libvncserver/scale.c Thu Aug 03 09:22:38 2006 *************** *** 151,156 **** --- 151,161 ---- h1 = h0; rfbScaledCorrection(screen, ptr, &x1, &y1, &w1, &h1, "rfbScaledScreenUpdateRect"); + // nyama/2006/08/02:This must be bug! Buffer over run when x0,y0 is unaligned. + 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,204 **** /* 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)]; pixel_value = 0; --- 202,210 ---- /* Get the totals for rgb from the source grid... */ for (w = 0; w < areaX; w++) { for (v = 0; v < areaY; v++) { ! // nyama/2006/08/02:This is minor bug because areaX is same with areaY in almost case. ! srcptr2 = &srcptr[(((x * areaX) + w) * bytesPerPixel) + ! (v * screen->paddedWidthInBytes)]; pixel_value = 0; diff -rcN ../LibVNCServer-0.8.2.org/libvncserver/zrle.c ./libvncserver/zrle.c *** ../LibVNCServer-0.8.2.org/libvncserver/zrle.c Wed Aug 02 14:41:53 2006 --- ./libvncserver/zrle.c Thu Aug 31 13:45:00 2006 *************** *** 40,57 **** --- 40,89 ---- #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 *************** *** 80,85 **** --- 112,131 ---- rfbZRLEHeader hdr; int i; + if( cl->preferredEncoding == rfbEncodingZYWRLE ){ + if( cl->tightQualityLevel < 0 ){ + zywrle_level = 1; + }else if( cl->tightQualityLevel < 3 ){ + zywrle_level = 3; + }else if( cl->tightQualityLevel < 6 ){ + zywrle_level = 2; + }else{ + zywrle_level = 1; + } + }else{ + zywrle_level = 0; + } + if (!cl->zrleData) cl->zrleData = zrleOutStreamNew(); zos = cl->zrleData; *************** *** 89,99 **** switch (cl->format.bitsPerPixel) { case 8: ! zrleEncode8( x, y, w, h, zos, zrleBeforeBuf, cl); break; case 16: ! zrleEncode16(x, y, w, h, zos, zrleBeforeBuf, cl); break; case 32: { --- 135,157 ---- switch (cl->format.bitsPerPixel) { case 8: ! zrleEncode8NE( x, y, w, h, zos, zrleBeforeBuf, cl); break; case 16: ! 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: { *************** *** 109,124 **** if ((fitsInLS3Bytes && !cl->format.bigEndian) || (fitsInMS3Bytes && cl->format.bigEndian)) { ! zrleEncode24A(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); } } break; --- 167,194 ---- if ((fitsInLS3Bytes && !cl->format.bigEndian) || (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)) { ! 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,144 **** rect.r.y = Swap16IfLE(y); rect.r.w = Swap16IfLE(w); rect.r.h = Swap16IfLE(h); ! rect.encoding = Swap32IfLE(rfbEncodingZRLE); memcpy(cl->updateBuf+cl->ublen, (char *)&rect, sz_rfbFramebufferUpdateRectHeader); --- 208,214 ---- rect.r.y = Swap16IfLE(y); rect.r.w = Swap16IfLE(w); rect.r.h = Swap16IfLE(h); ! rect.encoding = Swap32IfLE(cl->preferredEncoding); memcpy(cl->updateBuf+cl->ublen, (char *)&rect, sz_rfbFramebufferUpdateRectHeader); diff -rcN ../LibVNCServer-0.8.2.org/libvncserver/zrleencodetemplate.c ./libvncserver/zrleencodetemplate.c *** ../LibVNCServer-0.8.2.org/libvncserver/zrleencodetemplate.c Wed Aug 02 14:41:53 2006 --- ./libvncserver/zrleencodetemplate.c Thu Aug 31 13:41:39 2006 *************** *** 43,59 **** #define __RFB_CONCAT2E(a,b) __RFB_CONCAT2(a,b) #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 BPPOUT 24 #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 BPPOUT BPP #endif --- 43,79 ---- #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_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_CONCAT3E(zrleEncode,BPP,END_FIX) ! #define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX) #define BPPOUT BPP #endif *************** *** 64,75 **** --- 84,103 ---- 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }; + int zywrle_level; + int zywrleBuf[rfbZRLETileWidth*rfbZRLETileHeight]; + static zrlePaletteHelper paletteHelper; #endif /* ZRLE_ONCE */ void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os); + #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 EXTRA_ARGS *************** *** 144,149 **** --- 172,183 ---- 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,266 **** /* raw */ #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)); #endif } } } --- 287,310 ---- /* raw */ + #if BPP!=8 + if( (zywrle_level>0)&& !(zywrle_level & 0x80) ){ + ZYWRLE_ANALYZE( data, data, w, h, w, zywrle_level, zywrleBuf ); + zywrle_level |= 0x80; + ZRLE_ENCODE_TILE( data, w, h, os ); + zywrle_level &= 0x7F; + }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)); #endif + } } } } *************** *** 269,272 **** --- 313,317 ---- #undef zrleOutStreamWRITE_PIXEL #undef ZRLE_ENCODE #undef ZRLE_ENCODE_TILE + #undef ZYWRLE_ENCODE_TILE #undef BPPOUT diff -rcN ../LibVNCServer-0.8.2.org/libvncserver/zywrletemplate.c ./libvncserver/zywrletemplate.c *** ../LibVNCServer-0.8.2.org/libvncserver/zywrletemplate.c Thu Jan 01 09:00:00 1970 --- ./libvncserver/zywrletemplate.c Thu Aug 31 16:14:44 2006 *************** *** 0 **** --- 1,804 ---- + + /******************************************************************** + * * + * 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. + ********************************************************************/ + + //#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 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=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 ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,level,TRANS) \ + pH = pBuf; \ + s = 2<>1; \ + } \ + if( r & 0x02 ){ \ + pH += (s>>1)*width; \ + } \ + pEnd = pH+height*width; \ + while( pH < pEnd ){ \ + pLine = pH+width; \ + while( pH < pLine ){ \ + TRANS \ + data++; \ + pH += s; \ + } \ + pH += (s-1)*width; \ + } + + #define ZYWRLE_PACK_COEFF(pBuf,data,r,width,height,level) \ + ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,level,ZYWRLE_LOAD_COEFF(pH,R,G,B);ZYWRLE_SAVE_PIXEL(data,R,G,B);) + + #define ZYWRLE_UNPACK_COEFF(pBuf,data,r,width,height,level) \ + ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,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 = pTop + (w+uw)*(h+uh)-w*h; \ + while( pTop < pEnd ){ \ + TRANS \ + data++; \ + pTop++; \ + } + + #define ZYWRLE_LOAD_UNALIGN(data,pData,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<