?? coder_sm.c
字號:
/*****
SigMap : send "significance map" then residual values
the sigmap is a mask of five entries : "0,1,-1, positive > 1, negative < -1"
it is order-1 context coded bases on the the parents' sigmap entry.
if one of the later two escapes is sent, their magnitude is coded (the residual)
with an order-1 context coder based on the parents MSB (log2 of value)
(we use a truncated alphabet then do order-minus-1 on the rest)
could try better ways to code residuals
-----
S+P Lena lossless : 4.255 bpp
******/
#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 10 /** I'm very surprised that this tunes so high! **/
#define SIGMAP_CONTEXTS (CNTX_CAP+CNTX_CAP+1)
#define SIGMAP_ALPHABET 5 /** 0,1,-1,pos,neg **/
#define SIGMAP_TOTMAX 5000
#define SIGMAP_INC 30
#define ORDER0_CNTXMAX 8
#define ORDER0_CONTEXTS (ORDER0_CNTXMAX+1)
#define ORDER0_TOTMAX 500
#define ORDER0_ALPHABET 25
#define ORDER0_ESCAPE (ORDER0_ALPHABET-1)
#include "coder.h"
void coderSigMap_encodeBand(coder *me,int *band,int w,int h,int fullw,int *parent);
void coderSigMap_decodeBand(coder *me,int *band,int w,int h,int fullw,int *parent);
typedef struct {
ozero ** o0;
scontext ** o1;
} myInfo;
void coderSigMap_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 coderSigMap_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 coderSigMap = {
"SigMap",
coderSigMap_init,
coderSigMap_free,
coderSigMap_encodeBand,
coderSigMap_decodeBand
};
void coderSigMap_encodeBand(coder *me,int *band,int width,int height,int fullw,int *parent)
{
int x,y,val,cntx;
int *dp,*pp;
int par_val,par_sig;
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++) {
if ( coder_timetostop(me) ) { coder_didstop(me,y); return; }
for(x=0;x<width;x++) {
par_sig = pp[x>>1]; par_val = abs(par_sig);
par_sig = max(- CNTX_CAP,min(CNTX_CAP,par_sig)); par_sig += CNTX_CAP;
val = dp[x];
switch(val) {
case 0: scontextEncode(o1[par_sig],0); break;
case 1: scontextEncode(o1[par_sig],1); break;
case -1: scontextEncode(o1[par_sig],2); break;
default:
if ( isneg(val) ){ scontextEncode(o1[par_sig],3); val = -val; }
else scontextEncode(o1[par_sig],4);
val -= 2;
cntx = min(ORDER0_CNTXMAX, intlog2(par_val) );
if ( val < ORDER0_ESCAPE ) ozeroEncode(o0[cntx],val);
else {
ozeroEncode(o0[cntx],ORDER0_ESCAPE);
encode_m1(ari,val - ORDER0_ESCAPE);
}
break;
}
}
if ( y&1 ) pp += fullw;
dp += fullw;
}
}
void coderSigMap_decodeBand(coder *me,int *band,int width,int height,int fullw,int *parent)
{
int x,y,val,cntx,sign;
int *dp,*pp;
int par_val,par_sig;
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++) {
if ( coder_timetostopd(me,y) ) return;
for(x=0;x<width;x++) {
par_sig = pp[x>>1]; par_val = abs(par_sig);
par_sig = max(- CNTX_CAP,min(CNTX_CAP,par_sig)); par_sig += CNTX_CAP;
switch( scontextDecode(o1[par_sig]) ) {
case 0: dp[x] = 0; break;
case 1: dp[x] = 1; break;
case 2: dp[x] = -1; break;
case 3: sign = -1; goto decode_val;
case 4: sign = 1;
decode_val:
cntx = min(ORDER0_CNTXMAX, intlog2(par_val) );
val = ozeroDecode(o0[cntx]);
if( val == ORDER0_ESCAPE ) val += decode_m1(ari);
dp[x] = sign * (val + 2);
break;
default:
errexit("decoded past alphabet!");
}
}
if ( y&1 ) pp += fullw;
dp += fullw;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -