Fix ZYWRLE en/decoding for width != scanline (thanks Noriaki Yamazaki)

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
pull/1/head
dscho 17 years ago
parent 8bb8271615
commit befcb6fc14

@ -1,3 +1,7 @@
2008-02-04 Noriaki Yamazaki <micro-vnc@ias.hitachi-system.co.jp>
* libvncserver/zywrletemplate.c: Fix mis encode/decode when
width != scanline
2008-02-02 Johannes E. Schindelin <Johannes.Schindelin@gmx.de> 2008-02-02 Johannes E. Schindelin <Johannes.Schindelin@gmx.de>
* client_examples/SDLvncviewer.c: fix buttons (2 & 3 were switched), * client_examples/SDLvncviewer.c: fix buttons (2 & 3 were switched),
fix Tab key, and fix Ctrl+<letter> fix Tab key, and fix Ctrl+<letter>

@ -41,12 +41,19 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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_ENCODE */
/* #define ZYWRLE_DECODE */ /* #define ZYWRLE_DECODE */
#define ZYWRLE_QUANTIZE #define ZYWRLE_QUANTIZE
/* /*
[References] [References]
PLHarr: 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. 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: EZW:
@ -67,8 +74,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define ZYWRLE_LOAD_PIXEL __RFB_CONCAT2E(ZYWRLE_LOAD_PIXEL,BPP) #define ZYWRLE_LOAD_PIXEL __RFB_CONCAT2E(ZYWRLE_LOAD_PIXEL,BPP)
#define ZYWRLE_SAVE_PIXEL __RFB_CONCAT2E(ZYWRLE_SAVE_PIXEL,BPP) #define ZYWRLE_SAVE_PIXEL __RFB_CONCAT2E(ZYWRLE_SAVE_PIXEL,BPP)
/* Packing/Unpacking pixel stuffs. */ /* Packing/Unpacking pixel stuffs.
/* Endian conversion stuffs. */ Endian conversion stuffs. */
#undef S_0 #undef S_0
#undef S_1 #undef S_1
#undef L_0 #undef L_0
@ -147,11 +154,9 @@ const static unsigned int zywrleParam[3][3]={
{0x0000F000,0x00000000,0x00000000}, {0x0000F000,0x00000000,0x00000000},
{0x0000C000,0x00F0F0F0,0x00000000}, {0x0000C000,0x00F0F0F0,0x00000000},
{0x0000C000,0x00C0C0C0,0x00F0F0F0}, {0x0000C000,0x00C0C0C0,0x00F0F0F0},
/* /* {0x0000FF00,0x00000000,0x00000000},
{0x0000FF00,0x00000000,0x00000000},
{0x0000FF00,0x00FFFFFF,0x00000000}, {0x0000FF00,0x00FFFFFF,0x00000000},
{0x0000FF00,0x00FFFFFF,0x00FFFFFF}, {0x0000FF00,0x00FFFFFF,0x00FFFFFF}, */
*/
}; };
# else # else
/* Type B:Non liner quantization filter. */ /* Type B:Non liner quantization filter. */
@ -305,8 +310,8 @@ static InlineX void Harr(signed char* pX0, signed char* pX1)
{ {
/* Piecewise-Linear Harr(PLHarr) */ /* Piecewise-Linear Harr(PLHarr) */
int X0 = (int)*pX0, X1 = (int)*pX1; int X0 = (int)*pX0, X1 = (int)*pX1;
int orgX0=X0, orgX1=X1; int orgX0 = X0, orgX1 = X1;
if ((X0^X1) & 0x80) { if ((X0 ^ X1) & 0x80) {
/* differ sign */ /* differ sign */
X1 += X0; X1 += X0;
if (((X1^orgX1)&0x80)==0) { if (((X1^orgX1)&0x80)==0) {
@ -316,7 +321,7 @@ static InlineX void Harr(signed char* pX0, signed char* pX1)
} else { } else {
/* same sign */ /* same sign */
X0 -= X1; X0 -= X1;
if (((X0^orgX0) & 0x80) == 0) { if (((X0 ^ orgX0) & 0x80) == 0) {
/* |X0| > |X1| */ /* |X0| > |X1| */
X1 += X0; /* L = A */ X1 += X0; /* L = A */
} }
@ -345,7 +350,6 @@ static InlineX void Harr(signed char* pX0, signed char* pX1)
Of cause, the result of both method is quite same Of cause, the result of both method is quite same
because it's only difference that coefficient position. because it's only difference that coefficient position.
*/ */
static InlineX void WaveletLevel(int* data, int size, int l, int SkipPixel) static InlineX void WaveletLevel(int* data, int size, int l, int SkipPixel)
{ {
int s, ofs; int s, ofs;
@ -439,7 +443,6 @@ static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int le
the filtering procedure in future. the filtering procedure in future.
Client only decodes coefficients given by encoder. Client only decodes coefficients given by encoder.
*/ */
static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int level, int l) static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int level, int l)
{ {
int r, s; int r, s;
@ -485,7 +488,7 @@ static InlineX void Wavelet(int* pBuf, int width, int height, int level)
pTop = pBuf; pTop = pBuf;
pEnd = pBuf+width; pEnd = pBuf+width;
s = 1<<l; s = 1<<l;
while(pTop < pEnd) { while (pTop < pEnd) {
WaveletLevel(pTop, height,l, width); WaveletLevel(pTop, height,l, width);
pTop += s; pTop += s;
} }
@ -494,12 +497,13 @@ static InlineX void Wavelet(int* pBuf, int width, int height, int level)
} }
#endif #endif
#ifdef ZYWRLE_DECODE #ifdef ZYWRLE_DECODE
static InlineX void InvWavelet(int* pBuf, int width, int height, int level) { static InlineX void InvWavelet(int* pBuf, int width, int height, int level)
{
int l, s; int l, s;
int* pTop; int* pTop;
int* pEnd; int* pEnd;
for (l = level-1; l >= 0; l--) { for (l = level - 1; l >= 0; l--) {
pTop = pBuf; pTop = pBuf;
pEnd = pBuf+width; pEnd = pBuf+width;
s = 1<<l; s = 1<<l;
@ -518,8 +522,8 @@ static InlineX void InvWavelet(int* pBuf, int width, int height, int level) {
} }
#endif #endif
/* Load/Save coefficients stuffs. */ /* Load/Save coefficients stuffs.
/* Coefficients manages as 24 bits little-endian pixel. */ Coefficients manages as 24 bits little-endian pixel. */
#define ZYWRLE_LOAD_COEFF(pSrc,R,G,B) { \ #define ZYWRLE_LOAD_COEFF(pSrc,R,G,B) { \
R = ((signed char*)pSrc)[2]; \ R = ((signed char*)pSrc)[2]; \
G = ((signed char*)pSrc)[1]; \ G = ((signed char*)pSrc)[1]; \
@ -544,13 +548,10 @@ static InlineX void InvWavelet(int* pBuf, int width, int height, int level) {
U = B-G (-256<=U<=255) U = B-G (-256<=U<=255)
V = R-G (-256<=V<=255) V = R-G (-256<=V<=255)
*/ */
#define ROUND(x) (((x)<0)?0:(((x)>255)?255:(x))) #define ROUND(x) (((x)<0)?0:(((x)>255)?255:(x)))
/* /* RCT is N-bit RGB to N-bit Y and N+1-bit UV.
RCT is N-bit RGB to N-bit Y and N+1-bit UV.
For make Same N-bit, UV is lossy. For make Same N-bit, UV is lossy.
More exact PLHarr, we reduce to odd range(-127<=x<=127). More exact PLHarr, we reduce to odd range(-127<=x<=127). */
*/
#define ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ymask,uvmask) { \ #define ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ymask,uvmask) { \
Y = (R+(G<<1)+B)>>2; \ Y = (R+(G<<1)+B)>>2; \
U = B-G; \ U = B-G; \
@ -611,41 +612,47 @@ static InlineX void InvWavelet(int* pBuf, int width, int height, int level) {
| Hxy | | Hxy |
+------+------+ +------+------+
*/ */
#define INC_PTR(data) \
data++; \
if( data-pData >= (w+uw) ){ \
data += scanline-(w+uw); \
pData = data; \
}
#define ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,level,TRANS) \ #define ZYWRLE_TRANSFER_COEFF(pBuf,data,r,w,h,scanline,level,TRANS) \
pH = pBuf; \ pH = pBuf; \
s = 2<<level; \ s = 2<<level; \
if (r & 0x01) \ if (r & 0x01) \
pH += s>>1; \ pH += s>>1; \
if (r & 0x02) \ if (r & 0x02) \
pH += (s>>1)*width; \ pH += (s>>1)*w; \
pEnd = pH+height*width; \ pEnd = pH+h*w; \
while (pH < pEnd) { \ while (pH < pEnd) { \
pLine = pH+width; \ pLine = pH+w; \
while (pH < pLine) { \ while (pH < pLine) { \
TRANS \ TRANS \
data++; \ INC_PTR(data) \
pH += s; \ pH += s; \
} \ } \
pH += (s-1)*width; \ pH += (s-1)*w; \
} }
#define ZYWRLE_PACK_COEFF(pBuf,data,r,width,height,level) \ #define ZYWRLE_PACK_COEFF(pBuf,data,r,width,height,scanline,level) \
ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,level,ZYWRLE_LOAD_COEFF(pH,R,G,B);ZYWRLE_SAVE_PIXEL(data,R,G,B);) 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,level) \ #define ZYWRLE_UNPACK_COEFF(pBuf,data,r,width,height,scanline,level) \
ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,level,ZYWRLE_LOAD_PIXEL(data,R,G,B);ZYWRLE_SAVE_COEFF(pH,R,G,B);) 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) \ #define ZYWRLE_SAVE_UNALIGN(data,TRANS) \
pTop = pBuf+w*h; \ pTop = pBuf+w*h; \
pEnd = pTop + (w+uw)*(h+uh)-w*h; \ pEnd = pBuf + (w+uw)*(h+uh); \
while (pTop < pEnd) { \ while (pTop < pEnd) { \
TRANS \ TRANS \
data++; \ INC_PTR(data) \
pTop++; \ pTop++; \
} }
#define ZYWRLE_LOAD_UNALIGN(data,pData,TRANS) \ #define ZYWRLE_LOAD_UNALIGN(data,TRANS) \
pTop = pBuf+w*h; \ pTop = pBuf+w*h; \
if (uw) { \ if (uw) { \
pData= data + w; \ pData= data + w; \
@ -718,8 +725,7 @@ static InlineX void ZYWRLE_RGBYUV(int* pBuf, PIXEL_T* data, int width, int heigh
} }
#endif #endif
#ifdef ZYWRLE_DECODE #ifdef ZYWRLE_DECODE
static InlineX void ZYWRLE_YUVRGB(int* pBuf, PIXEL_T* data, int width, int height, int scanline) static InlineX void ZYWRLE_YUVRGB(int* pBuf, PIXEL_T* data, int width, int height, int scanline) {
{
int R, G, B; int R, G, B;
int Y, U, V; int Y, U, V;
int* pLine; int* pLine;
@ -740,15 +746,14 @@ static InlineX void ZYWRLE_YUVRGB(int* pBuf, PIXEL_T* data, int width, int heigh
#endif #endif
#ifdef ZYWRLE_ENCODE #ifdef ZYWRLE_ENCODE
PIXEL_T* ZYWRLE_ANALYZE (PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf) PIXEL_T* ZYWRLE_ANALYZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf) {
{
int l; int l;
int uw = w; int uw = w;
int uh = h; int uh = h;
int* pTop; int* pTop;
int* pEnd; int* pEnd;
int* pLine; int* pLine;
PIXEL_T* pSrc; PIXEL_T* pData;
int R, G, B; int R, G, B;
int s; int s;
int* pH; int* pH;
@ -759,15 +764,16 @@ PIXEL_T* ZYWRLE_ANALYZE (PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline,
uw -= w; uw -= w;
uh -= h; uh -= h;
ZYWRLE_LOAD_UNALIGN(src,pSrc,*(PIXEL_T*)pTop=*pSrc;) pData = dst;
ZYWRLE_LOAD_UNALIGN(src,*(PIXEL_T*)pTop=*pData;)
ZYWRLE_RGBYUV(pBuf, src, w, h, scanline); ZYWRLE_RGBYUV(pBuf, src, w, h, scanline);
Wavelet(pBuf, w, h, level); Wavelet(pBuf, w, h, level);
for (l = 0; l < level; l++) { for (l = 0; l < level; l++) {
ZYWRLE_PACK_COEFF(pBuf, dst, 3, w, h, l); ZYWRLE_PACK_COEFF(pBuf, dst, 3, w, h, scanline, l);
ZYWRLE_PACK_COEFF(pBuf, dst, 2, w, h, l); ZYWRLE_PACK_COEFF(pBuf, dst, 2, w, h, scanline, l);
ZYWRLE_PACK_COEFF(pBuf, dst, 1, w, h, l); ZYWRLE_PACK_COEFF(pBuf, dst, 1, w, h, scanline, l);
if (l == level-1) { if (l == level - 1) {
ZYWRLE_PACK_COEFF(pBuf, dst, 0, w, h, l); ZYWRLE_PACK_COEFF(pBuf, dst, 0, w, h, scanline, l);
} }
} }
ZYWRLE_SAVE_UNALIGN(dst,*dst=*(PIXEL_T*)pTop;) ZYWRLE_SAVE_UNALIGN(dst,*dst=*(PIXEL_T*)pTop;)
@ -783,7 +789,7 @@ PIXEL_T* ZYWRLE_SYNTHESIZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanlin
int* pTop; int* pTop;
int* pEnd; int* pEnd;
int* pLine; int* pLine;
PIXEL_T* pDst; PIXEL_T* pData;
int R, G, B; int R, G, B;
int s; int s;
int* pH; int* pH;
@ -794,18 +800,19 @@ PIXEL_T* ZYWRLE_SYNTHESIZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanlin
uw -= w; uw -= w;
uh -= h; uh -= h;
pData = src;
for (l = 0; l < level; l++) { for (l = 0; l < level; l++) {
ZYWRLE_UNPACK_COEFF(pBuf, src, 3, w, h, l); ZYWRLE_UNPACK_COEFF(pBuf, src, 3, w, h, scanline, l);
ZYWRLE_UNPACK_COEFF(pBuf, src, 2, w, h, l); ZYWRLE_UNPACK_COEFF(pBuf, src, 2, w, h, scanline, l);
ZYWRLE_UNPACK_COEFF(pBuf, src, 1, w, h, l); ZYWRLE_UNPACK_COEFF(pBuf, src, 1, w, h, scanline, l);
if (l == level-1) { if (l == level - 1) {
ZYWRLE_UNPACK_COEFF(pBuf, src, 0, w, h, l); ZYWRLE_UNPACK_COEFF(pBuf, src, 0, w, h, scanline, l);
} }
} }
ZYWRLE_SAVE_UNALIGN(src,*(PIXEL_T*)pTop=*src;) ZYWRLE_SAVE_UNALIGN(src,*(PIXEL_T*)pTop=*src;)
InvWavelet(pBuf, w, h, level); InvWavelet(pBuf, w, h, level);
ZYWRLE_YUVRGB(pBuf, dst, w, h, scanline); ZYWRLE_YUVRGB(pBuf, dst, w, h, scanline);
ZYWRLE_LOAD_UNALIGN(dst,pDst,*pDst=*(PIXEL_T*)pTop;) ZYWRLE_LOAD_UNALIGN(dst,*pData=*(PIXEL_T*)pTop;)
return src; return src;
} }
#endif #endif

Loading…
Cancel
Save