www.pudn.com > wavecode.rar > coder_sm_b.c


/***** 
 
SM2 : send "significance map" then residual values 
 
SM2 2 : 
 
 code the sigmap as four symbols (0,1,2,other) and send signs raw 
 
 code a quartet (with same parent) smashed together = 8 bits 
	(advantage : a bit faster, and gathers implicitly the dependence on neighbors 
	 disadvantage : larger alphabet thins statistics) 
 
 neither of these helped; this coder is left in as a lesson 
 
--- 
(btw using "scontext" for a 256-char alphabet is really inappropriate; we should 
correctly use the normal "context" coder with an escape down to an order0) 
 
******/ 
 
#include  
#include  
#include  
#include  
#include  
#include  
 
extern int tune_param; 
 
/*** some convenient debug routines: 
** #define SEND_TAG()	if(0); else { arithEncode(ari,43,44,77); } 
** #define GET_TAG()	if(0); else { int got; got = arithGet(ari,77); arithDecode(ari,43,44,77); if ( got != 43 ) errexit("tag failure"); } 
********/ 
 
#define CNTX_CAP			4 
#define SIGMAP_CONTEXTS		(CNTX_CAP+1) 
#define SIGMAP_ALPHABET		256		/** 8 bits **/ 
 
#define SIGMAP_TOTMAX		15000 
#define SIGMAP_INC			10 
 
#define ORDER0_CNTXMAX		8 
#define ORDER0_CONTEXTS		(ORDER0_CNTXMAX+1) 
#define ORDER0_TOTMAX		500 
#define ORDER0_ALPHABET		25 
#define ORDER0_ESCAPE		(ORDER0_ALPHABET-1) 
 
#define SIG_CNTX(val)	min(CNTX_CAP,intlog2(val+1))			/** min(CNTX_CAP,val) **/ 
#define O0_CNTX(val)	min(ORDER0_CNTXMAX, intlog2(val)) 
 
#include "coder.h" 
 
void coderSM2_encodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); 
void coderSM2_decodeBand(coder *me,int *band,int w,int h,int fullw,int *parent); 
 
typedef struct { 
	ozero ** o0; 
	scontext ** o1; 
} myInfo; 
 
void coderSM2_init(coder *c) 
{ 
myInfo *d; 
int i; 
 
	if ( (d = new(myInfo)) == NULL ) 
		errexit("ozero init failed"); 
 
	c->data = d; 
 
	if ( (d->o0 = newarray(void *,ORDER0_CONTEXTS)) == NULL ) 
		errexit("Order0_Init failed!"); 
 
	for(i=0;io0[i] = ozeroCreateMax(c->arith,ORDER0_ALPHABET,ORDER0_TOTMAX)) == NULL ) 
			errexit("ozero init failed"); 
 
	if ( (d->o1 = newarray(void *,SIGMAP_CONTEXTS)) == NULL ) 
		errexit("Order1_Init failed!"); 
 
	for(i=0;io1[i] = scontextCreate(c->arith,SIGMAP_ALPHABET,0, 
				SIGMAP_TOTMAX,SIGMAP_INC,true)) == NULL ) 
			errexit("context creation failed!"); 
 
} 
 
void coderSM2_free(coder *c) 
{ 
	if ( c->data ) { 
		myInfo *d; 
		d = c->data; 
		if ( d->o0 ) { 
			int i; 
			for(i=0;io0[i] ) ozeroFree(d->o0[i]); 
			free(d->o0); 
		} 
		if ( d->o1 ) { 
			int i; 
			for(i=0;io1[i] ) scontextFree(d->o1[i]); 
			} 
		} 
		free(d); 
		c->data = NULL; 
	} 
} 
 
coder coderSM2 = { 
		"SigMap 2", 
		coderSM2_init, 
		coderSM2_free, 
		coderSM2_encodeBand, 
		coderSM2_decodeBand 
	}; 
 
static void encode_val(arithInfo *ari,ozero *o0,int val) 
{ 
	if ( isneg(val) ) { arithBit(ari,1); val = -val; } 
	else arithBit(ari,0); 
 
	if ( val < 3 ) return; 
	val -= 3; 
 
	if ( val < ORDER0_ESCAPE ) ozeroEncode(o0,val); 
	else { 
		ozeroEncode(o0,ORDER0_ESCAPE);	 
		encode_m1(ari,val - ORDER0_ESCAPE); 
	} 
} 
 
static int decode_val(arithInfo *ari,ozero *o0) 
{ 
int sign,val; 
	if ( arithGetBit(ari) ) sign = -1; 
	else sign = 1; 
 
	val = ozeroDecode(o0); 
	if( val == ORDER0_ESCAPE ) val += decode_m1(ari); 
 
	val += 3; 
return val*sign; 
} 
 
void coderSM2_encodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) 
{ 
int x,y,A,B,C,D,block; 
int *dp,*pp,*dpn; 
int par_val,par_sig,cntx; 
ozero **o0 = ((myInfo *)me->data)->o0; 
scontext **o1 = ((myInfo *)me->data)->o1; 
arithInfo *ari = me->arith; 
 
	dp = band;	pp = parent; 
	for(y=0;y>1]); par_sig = SIG_CNTX(par_val); cntx = O0_CNTX(par_val); 
 
			A = dp[x];	B = dp[x+1]; 
			C = dpn[x];	D = dpn[x+1]; 
 
			block = 0; 
			switch(abs(A)) { case 0: break; case 1: block += 1; break; case 2: block += 2; break; default: block +=3; break; }  
			block <<= 2; 
			switch(abs(B)) { case 0: break; case 1: block += 1; break; case 2: block += 2; break; default: block +=3; break; } 
			block <<= 2; 
			switch(abs(C)) { case 0: break; case 1: block += 1; break; case 2: block += 2; break; default: block +=3; break; } 
			block <<= 2; 
			switch(abs(D)) { case 0: break; case 1: block += 1; break; case 2: block += 2; break; default: block +=3; break; } 
 
			scontextEncode(o1[par_sig],block); 
 
			if (D) encode_val(ari,o0[cntx],D); 
			if (C) encode_val(ari,o0[cntx],C); 
			if (B) encode_val(ari,o0[cntx],B); 
			if (A) encode_val(ari,o0[cntx],A); 
		} 
		pp += fullw; 
		dp += fullw + fullw; 
	} 
} 
 
void coderSM2_decodeBand(coder *me,int *band,int width,int height,int fullw,int *parent) 
{ 
int x,y,block,val; 
int *dp,*pp,*dpn; 
int par_val,par_sig,cntx; 
ozero **o0 = ((myInfo *)me->data)->o0; 
scontext **o1 = ((myInfo *)me->data)->o1; 
arithInfo *ari = me->arith; 
 
	dp = band;	pp = parent; 
	for(y=0;y>1]); par_sig = SIG_CNTX(par_val); cntx = O0_CNTX(par_val); 
 
			block = scontextDecode(o1[par_sig]); 
 
			/** go backwards, D,C,B,A **/ 
 
			switch(block&3) {	case 0: val=0; break; 
								case 1: if(arithGetBit(ari)) val=-1; else val=1; break; 
								case 2: if(arithGetBit(ari)) val=-2; else val=2; break; 
								case 3: val = decode_val(ari,o0[cntx]); break; } 
			dpn[x+1] = val; block >>= 2; 
			switch(block&3) {	case 0: val=0; break; 
								case 1: if(arithGetBit(ari)) val=-1; else val=1; break; 
								case 2: if(arithGetBit(ari)) val=-2; else val=2; break; 
								case 3: val = decode_val(ari,o0[cntx]); break; } 
			dpn[x] = val; block >>= 2; 
			switch(block&3) {	case 0: val=0; break; 
								case 1: if(arithGetBit(ari)) val=-1; else val=1; break; 
								case 2: if(arithGetBit(ari)) val=-2; else val=2; break; 
								case 3: val = decode_val(ari,o0[cntx]); break; } 
			dp[x+1] = val; block >>= 2; 
			switch(block&3) {	case 0: val=0; break; 
								case 1: if(arithGetBit(ari)) val=-1; else val=1; break; 
								case 2: if(arithGetBit(ari)) val=-2; else val=2; break; 
								case 3: val = decode_val(ari,o0[cntx]); break; } 
			dp[x] = val; block >>= 2; 
		} 
		pp += fullw; 
		dp += fullw + fullw; 
	} 
}