?? coder_o1p1.c
字號:
//#define SIGN_JUST_XOR /** much worse **/
/*********
a straightforward order1 coder : code pel conditioned on the
log2(parent)
"order1+1" also uses log2(neighbors) in the context
Order1 : S+P Lena lossless : 4.250 bpp
Order1+1: : 4.207 bpp
**********/
#include <stdio.h>
#include <stdlib.h>
#include <crblib/inc.h>
#include <crblib/arithc.h>
#include <crblib/o0coder.h>
#include <crblib/scontext.h>
extern int tune_param;
#define ORDER1_TOTMAX 10000
#define ORDER1_INC 15
#define ORDER1_ESCAPE 12
#define ORDER1_ALPHABET (ORDER1_ESCAPE+1)
#define CN_MAX_PREV 4
#define CN_MAX_PARENT 4
#define CODE_CONTEXTS (1 + CN_MAX_PREV + (CN_MAX_PREV+1)*CN_MAX_PARENT)
#define ORDER0_TOTMAX 2000 /** totally irrelevant **/
#define ORDER0_ESCAPE 1 /** optimal at 1 !!! a unary code!!! **/
#define ORDER0_ALPHABET (ORDER0_ESCAPE+1)
#include "coder.h"
void coderO1_1_encodeBand(coder *me,int *band,int w,int h,int fullw,int *parent);
void coderO1_1_decodeBand(coder *me,int *band,int w,int h,int fullw,int *parent);
typedef struct {
ozero * o0;
scontext * sign_sc[3];
scontext ** o1;
} myInfo;
void coderO1_1_init(coder *c)
{
myInfo *d;
int i;
if ( (d = new(myInfo)) == NULL )
errexit("ozero init failed");
c->data = d;
if ( (d->o0 = ozeroCreateMax(c->arith,ORDER0_ALPHABET,ORDER0_TOTMAX)) == NULL )
errexit("ozero init failed");
for(i=0;i<3;i++) {
if ( (d->sign_sc[i] = scontextCreate(c->arith,2,0,1000,10,true)) == NULL )
errexit("sign ozero init failed");
}
if ( (d->o1 = newarray(void *,CODE_CONTEXTS)) == NULL )
errexit("Order1_Init failed!");
for(i=0;i<CODE_CONTEXTS;i++) {
if ( (d->o1[i] = scontextCreate(c->arith,ORDER1_ALPHABET,0,
ORDER1_TOTMAX,ORDER1_INC,true)) == NULL )
errexit("context creation failed!");
}
}
void coderO1_1_free(coder *c)
{
if ( c->data ) {
myInfo *d; int i;
d = c->data;
if ( d->o0 ) ozeroFree(d->o0);
for(i=0;i<3;i++) {
if ( d->sign_sc[i] ) scontextFree(d->sign_sc[i]);
}
if ( d->o1 ) {
for(i=0;i<CODE_CONTEXTS;i++) {
if ( d->o1[i] ) scontextFree(d->o1[i]);
}
}
free(d);
c->data = NULL;
}
}
coder coderO1_1 = {
"o1+1",
coderO1_1_init,
coderO1_1_free,
coderO1_1_encodeBand,
coderO1_1_decodeBand
};
static void mcontext(int *cur_ptr,int parent,int x,int y,int width,int height,int fullw,
int *cntx_ptr,int *sign_ptr)
{
int neighbors;
/** cur_ptr[0] is about to be coded **/
if ( x==0 ) {
if ( y == 0 ) {
neighbors = 0;
} else {
neighbors = (cur_ptr[-fullw] + cur_ptr[-fullw+1]) >> 1;
}
} else if ( y == 0 ) {
neighbors = cur_ptr[-1];
} else if ( x == (width-1) ) {
neighbors = (cur_ptr[-1] + cur_ptr[-fullw] + cur_ptr[-fullw] + cur_ptr[-fullw-1]) >> 2;
} else {
neighbors = (cur_ptr[-1] + cur_ptr[-fullw] + cur_ptr[-fullw+1] + cur_ptr[-fullw-1]) >> 2;
}
if ( neighbors == 0 ) *sign_ptr = 2;
else if ( isneg(neighbors) ) *sign_ptr = 1;
else *sign_ptr = 0;
parent = abs(parent);
neighbors = abs(neighbors);
parent = intlog2(parent+1);
neighbors = intlog2(neighbors);
*cntx_ptr = min(CN_MAX_PREV,neighbors) + (CN_MAX_PREV+1)*(min(CN_MAX_PARENT,parent));
}
void coderO1_1_encodeBand(coder *me,int *band,int width,int height,int fullw,int *parent)
{
int x,y,val,cntx,sign,sign_cntx;
int *dp,*pp,*dpp,*ppp;
ozero *o0 = ((myInfo *)me->data)->o0;
scontext **sign_sc = ((myInfo *)me->data)->sign_sc;
scontext **o1 = ((myInfo *)me->data)->o1;
arithInfo *ari = me->arith;
dp = band;
pp = parent;
for(y=0;y<height;y++) {
dpp = dp; ppp = pp;
if ( coder_timetostop(me) ) { coder_didstop(me,y); return; }
for(x=0;x<width;x++) {
mcontext(dpp,*ppp,x,y,width,height,fullw,&cntx,&sign_cntx);
val = *dpp++; if ( x&1 ) ppp++;
if ( val == 0 ) {
scontextEncode(o1[cntx],0);
continue;
} else if ( val < 0 ) { sign = 1; val = -val;
} else sign = 0;
if ( val < ORDER1_ESCAPE ) {
scontextEncode(o1[cntx],val);
} else {
scontextEncode(o1[cntx],ORDER1_ESCAPE);
val -= ORDER1_ESCAPE;
while( val >= ORDER0_ESCAPE ) {
ozeroEncode(o0,ORDER0_ESCAPE);
val -= ORDER0_ESCAPE;
}
ozeroEncode(o0,val);
}
#ifdef SIGN_JUST_XOR
if ( sign_cntx != 2 ) sign ^= sign_cntx;
scontextEncode(sign_sc[0],sign);
#else
scontextEncode(sign_sc[sign_cntx],sign);
#endif // SIGN_JUST_XOR
}
if ( y & 1 ) pp += fullw;
dp += fullw;
}
}
void coderO1_1_decodeBand(coder *me,int *band,int width,int height,int fullw,int *parent)
{
int x,y,val,cntx,sign,got,sign_cntx;
int *dp,*pp,*dpp,*ppp;
ozero *o0 = ((myInfo *)me->data)->o0;
scontext **sign_sc = ((myInfo *)me->data)->sign_sc;
scontext **o1 = ((myInfo *)me->data)->o1;
arithInfo *ari = me->arith;
dp = band;
pp = parent;
for(y=0;y<height;y++) {
dpp = dp; ppp = pp;
if ( coder_timetostopd(me,y) ) return;
for(x=0;x<width;x++) {
mcontext(dpp,*ppp,x,y,width,height,fullw,&cntx,&sign_cntx);
if ( x&1 ) ppp++;
got = scontextDecode(o1[cntx]);
if ( got == 0 ) {
*dpp++ = 0;
continue;
} else if ( got < ORDER1_ESCAPE ) {
val = got;
} else {
val = ORDER1_ESCAPE;
got = ozeroDecode(o0);
while ( got == ORDER0_ESCAPE ) {
val += ORDER0_ESCAPE;
got = ozeroDecode(o0);
}
val += got;
}
#ifdef SIGN_JUST_XOR
if ( scontextDecode(sign_sc[0]) ) {
if ( sign_cntx == 2 || sign_cntx == 0 ) val = -val;
} else {
if ( sign_cntx == 1 ) val = -val;
}
#else
if ( scontextDecode(sign_sc[sign_cntx]) ) val = -val;
#endif // SIGN_JUST_XOR
*dpp++ = val;
}
if ( y & 1 ) pp += fullw;
dp += fullw;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -