?? 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 <stdio.h>
#include <stdlib.h>
#include <crblib/inc.h>
#include <crblib/arithc.h>
#include <crblib/scontext.h>
#include <crblib/o0coder.h>
#include <crblib/intmath.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 + -