diff options
Diffstat (limited to 'libvncserver/zywrletemplate.c')
| -rw-r--r-- | libvncserver/zywrletemplate.c | 824 |
1 files changed, 0 insertions, 824 deletions
diff --git a/libvncserver/zywrletemplate.c b/libvncserver/zywrletemplate.c deleted file mode 100644 index 52b2b0b..0000000 --- a/libvncserver/zywrletemplate.c +++ /dev/null @@ -1,824 +0,0 @@ - -/******************************************************************** - * * - * 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)*SkipPixel; - end = pX0+(size>>(l+1))*s; - s -= 2; - ofs = (4<<l)*SkipPixel; - while (pX0 < end) { - Harr(pX0, pX0+ofs); - pX0++; - Harr(pX0, pX0+ofs); - pX0++; - Harr(pX0, pX0+ofs); - pX0 += s; - } -} -#define InvWaveletLevel(d,s,l,pix) WaveletLevel(d,s,l,pix) - -#ifdef ZYWRLE_ENCODE -# ifndef ZYWRLE_QUANTIZE -/* Type A:lower bit omitting of EZW style. */ -static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int level, int l) -{ - int r, s; - int x, y; - int* pH; - const unsigned int* pM; - - pM = &(zywrleParam[level-1][l]); - s = 2<<l; - for (r = 1; r < 4; r++) { - pH = pBuf; - if (r & 0x01) - pH += s>>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<<l; - for (r = 1; r < 4; r++) { - pH = pBuf; - if (r & 0x01) - pH += s>>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<<l; - while (pTop < pEnd) { - WaveletLevel(pTop, width, l, 1); - pTop += s; - } - pTop = pBuf; - pEnd = pBuf+width; - s = 1<<l; - while (pTop < pEnd) { - WaveletLevel(pTop, height,l, width); - pTop += s; - } - FilterWaveletSquare(pBuf, width, height, level, l); - } -} -#endif -#ifdef ZYWRLE_DECODE -static InlineX void InvWavelet(int* pBuf, int width, int height, int level) -{ - int l, s; - int* pTop; - int* pEnd; - - for (l = level - 1; l >= 0; l--) { - pTop = pBuf; - pEnd = pBuf+width; - s = 1<<l; - while (pTop < pEnd) { - InvWaveletLevel(pTop, height,l, width); - pTop += s; - } - pTop = pBuf; - pEnd = pBuf+height*width; - s = width<<l; - while (pTop < pEnd) { - InvWaveletLevel(pTop, width, l, 1); - pTop += s; - } - } -} -#endif - -/* Load/Save coefficients stuffs. - Coefficients manages as 24 bits little-endian pixel. */ -#define ZYWRLE_LOAD_COEFF(pSrc,R,G,B) { \ - R = ((signed char*)pSrc)[2]; \ - G = ((signed char*)pSrc)[1]; \ - B = ((signed char*)pSrc)[0]; \ -} -#define ZYWRLE_SAVE_COEFF(pDst,R,G,B) { \ - ((signed char*)pDst)[2] = (signed char)R; \ - ((signed char*)pDst)[1] = (signed char)G; \ - ((signed char*)pDst)[0] = (signed char)B; \ -} - -/* - RGB <=> 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<<level; \ - if (r & 0x01) \ - pH += s>>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<<level)-1); - *pH &= ~((1<<level)-1); -} - -#endif /* ZYWRLE_ONCE */ - -#ifndef CPIXEL -#ifdef ZYWRLE_ENCODE -static InlineX void ZYWRLE_RGBYUV(int* pBuf, PIXEL_T* data, int width, int height, int scanline) -{ - int R, G, B; - int Y, U, V; - int* pLine; - int* pEnd; - pEnd = pBuf+height*width; - while (pBuf < pEnd) { - pLine = pBuf+width; - while (pBuf < pLine) { - ZYWRLE_LOAD_PIXEL(data,R,G,B); - ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ZYWRLE_YMASK,ZYWRLE_UVMASK); - ZYWRLE_SAVE_COEFF(pBuf,V,Y,U); - pBuf++; - data++; - } - data += scanline-width; - } -} -#endif -#ifdef ZYWRLE_DECODE -static InlineX void ZYWRLE_YUVRGB(int* pBuf, PIXEL_T* data, int width, int height, int scanline) { - int R, G, B; - int Y, U, V; - int* pLine; - int* pEnd; - pEnd = pBuf+height*width; - while (pBuf < pEnd) { - pLine = pBuf+width; - while (pBuf < pLine) { - ZYWRLE_LOAD_COEFF(pBuf,V,Y,U); - ZYWRLE_YUVRGB1(R,G,B,Y,U,V); - ZYWRLE_SAVE_PIXEL(data,R,G,B); - pBuf++; - data++; - } - data += scanline-width; - } -} -#endif - -#ifdef ZYWRLE_ENCODE -PIXEL_T* ZYWRLE_ANALYZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf) { - int l; - int uw = w; - int uh = h; - int* pTop; - int* pEnd; - int* pLine; - PIXEL_T* pData; - int R, G, B; - int s; - int* pH; - - zywrleCalcSize(&w, &h, level); - if (w == 0 || h == 0) - return NULL; - uw -= w; - uh -= h; - - pData = dst; - ZYWRLE_LOAD_UNALIGN(src,*(PIXEL_T*)pTop=*pData;) - ZYWRLE_RGBYUV(pBuf, src, w, h, scanline); - Wavelet(pBuf, w, h, level); - for (l = 0; l < level; l++) { - ZYWRLE_PACK_COEFF(pBuf, dst, 3, w, h, scanline, l); - ZYWRLE_PACK_COEFF(pBuf, dst, 2, w, h, scanline, l); - ZYWRLE_PACK_COEFF(pBuf, dst, 1, w, h, scanline, l); - if (l == level - 1) { - ZYWRLE_PACK_COEFF(pBuf, dst, 0, w, h, scanline, l); - } - } - ZYWRLE_SAVE_UNALIGN(dst,*dst=*(PIXEL_T*)pTop;) - return dst; -} -#endif -#ifdef ZYWRLE_DECODE -PIXEL_T* ZYWRLE_SYNTHESIZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf) -{ - int l; - int uw = w; - int uh = h; - int* pTop; - int* pEnd; - int* pLine; - PIXEL_T* pData; - int R, G, B; - int s; - int* pH; - - zywrleCalcSize(&w, &h, level); - if (w == 0 || h == 0) - return NULL; - uw -= w; - uh -= h; - - pData = src; - for (l = 0; l < level; l++) { - ZYWRLE_UNPACK_COEFF(pBuf, src, 3, w, h, scanline, l); - ZYWRLE_UNPACK_COEFF(pBuf, src, 2, w, h, scanline, l); - ZYWRLE_UNPACK_COEFF(pBuf, src, 1, w, h, scanline, l); - if (l == level - 1) { - ZYWRLE_UNPACK_COEFF(pBuf, src, 0, w, h, scanline, l); - } - } - ZYWRLE_SAVE_UNALIGN(src,*(PIXEL_T*)pTop=*src;) - InvWavelet(pBuf, w, h, level); - ZYWRLE_YUVRGB(pBuf, dst, w, h, scanline); - ZYWRLE_LOAD_UNALIGN(dst,*pData=*(PIXEL_T*)pTop;) - return src; -} -#endif -#endif /* CPIXEL */ - -#undef ZYWRLE_RGBYUV -#undef ZYWRLE_YUVRGB -#undef ZYWRLE_LOAD_PIXEL -#undef ZYWRLE_SAVE_PIXEL |
