?? coder_bp_zt.c
字號:
/*****
coder_BP :
could get more speed out of arithc and scontext
*****/
#include <stdio.h>
#include <stdlib.h>
#include <crblib/inc.h>
#include <crblib/arithc.h>
#include <crblib/scontext.h>
#include "coder.h"
extern int tune_param;
#define bitModel(bit,P0,PT) do { PT += INC; if (!(bit)) P0 += INC; if ( PT > TOTMAX ) { PT >>= 1; P0 >>= 1; P0++; PT += 2; } } while(0)
#define bitEnc(bit,ari,P0,PT) do { arithEncBit(ari,P0,PT,bit); bitModel(bit,P0,PT); } while(0)
#define bitDec(bit,ari,P0,PT) do { bit = arithDecBit(ari,P0,PT); bitModel(bit,P0,PT); } while(0)
#define INC 20
#define TOTMAX 4000
#define ORDER1_CONTEXTS 5
#define ORDER1_ALPHABET 16 //4 bits
#define ORDER1_TOTMAX 15000
#define ORDER1_INC 30
void coderBPZT_encodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows);
void coderBPZT_decodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows);
typedef struct {
scontext ** o1;
int zeros_p0[ORDER1_CONTEXTS],zeros_pt[ORDER1_CONTEXTS];
} myInfo;
void coderBPZT_init(coder *c)
{
myInfo *d;
int i;
if ( (d = new(myInfo)) == NULL )
errexit("ozero init failed");
c->data = d;
if ( (d->o1 = newarray(void *,ORDER1_CONTEXTS)) == NULL )
errexit("Order1_Init failed!");
for(i=0;i<ORDER1_CONTEXTS;i++) {
if ( (d->o1[i] = scontextCreate(c->arith,ORDER1_ALPHABET,0,
ORDER1_TOTMAX,ORDER1_INC,true)) == NULL )
errexit("context creation failed!");
d->zeros_p0[i] = 1; d->zeros_pt[i] = 2;
}
}
void coderBPZT_free(coder *c)
{
if ( c->data ) {
myInfo *d;
d = c->data;
if ( d->o1 ) {
int i;
for(i=0;i<ORDER1_CONTEXTS;i++) {
if ( d->o1[i] ) scontextFree(d->o1[i]);
}
}
free(d);
c->data = NULL;
}
}
coder coderBPZT = {
"BP ZeroTree",
coderBPZT_init,
coderBPZT_free,
NULL,NULL,NULL,NULL,
coderBPZT_encodeBandZT,
coderBPZT_decodeBandZT
};
void coderBPZT_encodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows)
{
int x,y,context,block;
int *dp,*dpn;
scontext **o1 = ((myInfo *)me->data)->o1;
arithInfo *ari = me->arith;
int donemask,nextmask,bitmask;
int *zeros_p0,*zeros_pt;
bool bottom;
zeros_p0 = ((myInfo *)me->data)->zeros_p0;
zeros_pt = ((myInfo *)me->data)->zeros_pt;
if ( width == (fullw>>1) ) bottom = true;
else bottom = false;
bitmask = 1<<bits;
for(x=bitmask,nextmask=0; x<CODE_MAX_VAL ;x<<=1) nextmask += x;
donemask = nextmask - bitmask;
dp = band;
for(y=0;y<height;y+=2) {
dpn = dp + fullw;
for(x=0;x<width;x+=2) {
if ( dp[0] & FLAG_CHILD_ZERO ) { // the whole quartet is zero
dp[0] -= FLAG_CHILD_ZERO; // it's a zerotree child, don't code
#if 1
dp[1] -= FLAG_CHILD_ZERO; // undo the evil unnecessary work of FindZeroTrees
dpn[0] -= FLAG_CHILD_ZERO;
dpn[1] -= FLAG_CHILD_ZERO;
#endif
} else {
context = ((dp[0] & donemask)?1:0) + ((dp[1] & donemask)?1:0) + ((dpn[0] & donemask)?1:0) + ((dpn[1] & donemask)?1:0);
block = 0; // 4 bits
if ( dp[0] & bitmask ) block += 1;
if ( dp[1] & bitmask ) block += 2;
if ( dpn[0] & bitmask ) block += 4;
if ( dpn[1] & bitmask ) block += 8;
scontextEncode(o1[context],block);
if ( ! bottom ) {
/** code zerotree flags on any zero bits **/
switch(block) {
case 15:
break;
case 14:
if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 13:
if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 12:
if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 11:
if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 10:
if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 9:
if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 8:
if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 7:
if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 6:
if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 5:
if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 4:
if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 3:
if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 2:
if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 1:
if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
case 0:
if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); }
break;
}
}
}
dp += 2; dpn += 2;
}
dp += fullw + fullw - width;
}
}
void coderBPZT_decodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows)
{
int x,y,context,block;
int *dp,*dpn;
scontext **o1 = ((myInfo *)me->data)->o1;
arithInfo *ari = me->arith;
int donemask,nextmask,bitmask;
int offwidth,offheight,*children;
int bit,tx,ty;
int *zeros_p0,*zeros_pt;
bool bottom;
zeros_p0 = ((myInfo *)me->data)->zeros_p0;
zeros_pt = ((myInfo *)me->data)->zeros_pt;
if ( width == (fullw>>1) ) bottom = true;
else bottom = false;
bitmask = 1<<bits;
for(x=bitmask,nextmask=0; x<CODE_MAX_VAL ;x<<=1) nextmask += x;
donemask = nextmask - bitmask;
offheight = (band - rows[0])/fullw;
offwidth = (band - rows[0]) - fullw*offheight;
dp = band;
for(y=0;y<height;y+=2) {
dpn = dp + fullw;
for(x=0;x<width;x+=2) {
if ( dp[0] & FLAG_ALREADY_DECODED ) {
dp[0] -= FLAG_ALREADY_DECODED;
if ( ! bottom ) {
tx = (offwidth + x)<<1;
ty = (offheight+ y)<<1;
rows[ty ][tx ] += FLAG_ALREADY_DECODED;
rows[ty ][tx+2] += FLAG_ALREADY_DECODED;
rows[ty+2][tx ] += FLAG_ALREADY_DECODED;
rows[ty+2][tx+2] += FLAG_ALREADY_DECODED;
}
} else {
context = ((dp[0] & donemask)?1:0) + ((dp[1] & donemask)?1:0) + ((dpn[0] & donemask)?1:0) + ((dpn[1] & donemask)?1:0);
block = scontextDecode(o1[context]);
if ( ! bottom )
children = rows[(offheight+ y)<<1] + ((offwidth + x)<<1);
if ( block & 1 ) dp[0 ] += bitmask;
else if ( ! bottom ) {
bitDec(bit,ari,zeros_p0[context],zeros_pt[context]);
if ( bit ) children[0] += FLAG_ALREADY_DECODED;
}
if ( block & 2 ) dp[1 ] += bitmask;
else if ( ! bottom ) {
bitDec(bit,ari,zeros_p0[context],zeros_pt[context]);
if ( bit ) children[2] += FLAG_ALREADY_DECODED;
}
if ( block & 4 ) dpn[0] += bitmask;
else if ( ! bottom ) {
bitDec(bit,ari,zeros_p0[context],zeros_pt[context]);
if ( bit ) children[fullw+fullw] += FLAG_ALREADY_DECODED;
}
if ( block & 8 ) dpn[1] += bitmask;
else if ( ! bottom ) {
bitDec(bit,ari,zeros_p0[context],zeros_pt[context]);
if ( bit ) children[fullw+fullw+2] += FLAG_ALREADY_DECODED;
}
}
dp += 2; dpn += 2;
}
dp += fullw + fullw - width;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -