Commit befcb6fc authored by dscho's avatar dscho

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

Signed-off-by: 's avatarJohannes Schindelin <johannes.schindelin@gmx.de>
parent 8bb82716
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>
* client_examples/SDLvncviewer.c: fix buttons (2 & 3 were switched),
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.
********************************************************************/
/* 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]
[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:
......@@ -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_SAVE_PIXEL __RFB_CONCAT2E(ZYWRLE_SAVE_PIXEL,BPP)
/* Packing/Unpacking pixel stuffs. */
/* Endian conversion stuffs. */
/* Packing/Unpacking pixel stuffs.
Endian conversion stuffs. */
#undef S_0
#undef S_1
#undef L_0
......@@ -147,11 +154,9 @@ const static unsigned int zywrleParam[3][3]={
{0x0000F000,0x00000000,0x00000000},
{0x0000C000,0x00F0F0F0,0x00000000},
{0x0000C000,0x00C0C0C0,0x00F0F0F0},
/*
{0x0000FF00,0x00000000,0x00000000},
/* {0x0000FF00,0x00000000,0x00000000},
{0x0000FF00,0x00FFFFFF,0x00000000},
{0x0000FF00,0x00FFFFFF,0x00FFFFFF},
*/
{0x0000FF00,0x00FFFFFF,0x00FFFFFF}, */
};
# else
/* Type B:Non liner quantization filter. */
......@@ -305,8 +310,8 @@ 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) {
int orgX0 = X0, orgX1 = X1;
if ((X0 ^ X1) & 0x80) {
/* differ sign */
X1 += X0;
if (((X1^orgX1)&0x80)==0) {
......@@ -316,7 +321,7 @@ static InlineX void Harr(signed char* pX0, signed char* pX1)
} else {
/* same sign */
X0 -= X1;
if (((X0^orgX0) & 0x80) == 0) {
if (((X0 ^ orgX0) & 0x80) == 0) {
/* |X0| > |X1| */
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
because it's only difference that coefficient position.
*/
static InlineX void WaveletLevel(int* data, int size, int l, int SkipPixel)
{
int s, ofs;
......@@ -439,7 +443,6 @@ static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int le
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;
......@@ -485,7 +488,7 @@ static InlineX void Wavelet(int* pBuf, int width, int height, int level)
pTop = pBuf;
pEnd = pBuf+width;
s = 1<<l;
while(pTop < pEnd) {
while (pTop < pEnd) {
WaveletLevel(pTop, height,l, width);
pTop += s;
}
......@@ -494,12 +497,13 @@ static InlineX void Wavelet(int* pBuf, int width, int height, int level)
}
#endif
#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* pTop;
int* pEnd;
for (l = level-1; l >= 0; l--) {
for (l = level - 1; l >= 0; l--) {
pTop = pBuf;
pEnd = pBuf+width;
s = 1<<l;
......@@ -518,8 +522,8 @@ static InlineX void InvWavelet(int* pBuf, int width, int height, int level) {
}
#endif
/* Load/Save coefficients stuffs. */
/* Coefficients manages as 24 bits little-endian pixel. */
/* 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]; \
......@@ -544,13 +548,10 @@ static InlineX void InvWavelet(int* pBuf, int width, int height, int level) {
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.
/* 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).
*/
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; \
......@@ -611,41 +612,47 @@ static InlineX void InvWavelet(int* pBuf, int width, int height, int level) {
| 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; \
s = 2<<level; \
if (r & 0x01) \
pH += s>>1; \
if (r & 0x02) \
pH += (s>>1)*width; \
pEnd = pH+height*width; \
pH += (s>>1)*w; \
pEnd = pH+h*w; \
while (pH < pEnd) { \
pLine = pH+width; \
pLine = pH+w; \
while (pH < pLine) { \
TRANS \
data++; \
INC_PTR(data) \
pH += s; \
} \
pH += (s-1)*width; \
pH += (s-1)*w; \
}
#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_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,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_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 = pTop + (w+uw)*(h+uh)-w*h; \
pEnd = pBuf + (w+uw)*(h+uh); \
while (pTop < pEnd) { \
TRANS \
data++; \
INC_PTR(data) \
pTop++; \
}
#define ZYWRLE_LOAD_UNALIGN(data,pData,TRANS) \
#define ZYWRLE_LOAD_UNALIGN(data,TRANS) \
pTop = pBuf+w*h; \
if (uw) { \
pData= data + w; \
......@@ -718,8 +725,7 @@ static InlineX void ZYWRLE_RGBYUV(int* pBuf, PIXEL_T* data, int width, int heigh
}
#endif
#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 Y, U, V;
int* pLine;
......@@ -740,15 +746,14 @@ static InlineX void ZYWRLE_YUVRGB(int* pBuf, PIXEL_T* data, int width, int heigh
#endif
#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 uw = w;
int uh = h;
int* pTop;
int* pEnd;
int* pLine;
PIXEL_T* pSrc;
PIXEL_T* pData;
int R, G, B;
int s;
int* pH;
......@@ -759,15 +764,16 @@ PIXEL_T* ZYWRLE_ANALYZE (PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline,
uw -= w;
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);
Wavelet(pBuf, w, h, level);
for (l = 0; l < level; l++) {
ZYWRLE_PACK_COEFF(pBuf, dst, 3, w, h, l);
ZYWRLE_PACK_COEFF(pBuf, dst, 2, w, h, l);
ZYWRLE_PACK_COEFF(pBuf, dst, 1, w, h, l);
if (l == level-1) {
ZYWRLE_PACK_COEFF(pBuf, dst, 0, w, h, 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;)
......@@ -783,7 +789,7 @@ PIXEL_T* ZYWRLE_SYNTHESIZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanlin
int* pTop;
int* pEnd;
int* pLine;
PIXEL_T* pDst;
PIXEL_T* pData;
int R, G, B;
int s;
int* pH;
......@@ -794,18 +800,19 @@ PIXEL_T* ZYWRLE_SYNTHESIZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanlin
uw -= w;
uh -= h;
pData = src;
for (l = 0; l < level; l++) {
ZYWRLE_UNPACK_COEFF(pBuf, src, 3, w, h, l);
ZYWRLE_UNPACK_COEFF(pBuf, src, 2, w, h, l);
ZYWRLE_UNPACK_COEFF(pBuf, src, 1, w, h, l);
if (l == level-1) {
ZYWRLE_UNPACK_COEFF(pBuf, src, 0, w, h, 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,pDst,*pDst=*(PIXEL_T*)pTop;)
ZYWRLE_LOAD_UNALIGN(dst,*pData=*(PIXEL_T*)pTop;)
return src;
}
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment