⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 coder_sm_b.c

📁 基于小波的图像压缩
💻 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 <stdio.h>
#include <stdlib.h>
#include <crblib/inc.h>
#include <crblib/arithc.h>
#include <crblib/scontext.h>
#include <crblib/o0coder.h>

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;i<ORDER0_CONTEXTS;i++)
		if ( (d->o0[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;i<SIGMAP_CONTEXTS;i++)
		if ( (d->o1[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;i<ORDER0_CONTEXTS;i++)
				if ( d->o0[i] ) ozeroFree(d->o0[i]);
			free(d->o0);
		}
		if ( d->o1 ) {
			int i;
			for(i=0;i<SIGMAP_CONTEXTS;i++) {
				if ( d->o1[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<height;y+=2) {
		if ( coder_timetostop(me) ) { coder_didstop(me,y); return; }
		dpn = dp + fullw;
		for(x=0;x<width;x+=2) {	/** x & y are the parent's location *2 **/
			par_val = abs(pp[x>>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<height;y+=2) {
		if ( coder_timetostopd(me,y) ) return;
		dpn = dp + fullw;
		for(x=0;x<width;x+=2) {	/** x & y are the parent's location *2 **/
			par_val = abs(pp[x>>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;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -