?? coder_zf.c
字號:
/*****
ZeroFlag coder:
codes bytewise but only using binary arithcoders.
sends "is byte == 0" (conditioned on activity of N and W)
then sign (conditioned on signs of N and W)
then (abs(byte)-1) using a unary adaptive binary code
fast AND excellent compression
*****/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crblib/inc.h>
#include <crblib/arithc.h>
#include "coder.h"
extern int tune_param;
#define VAL_CONTEXTS 16
#define VAL_CONTEXT_MAX (VAL_CONTEXTS -1)
#define NUM_CONTEXTS VAL_CONTEXTS
#define TAIL_CONTEXTS VAL_CONTEXTS
#define SIGN_CONTEXTS 4
#define TOTMAX 4000
#define INC 30
#define P0_INIT 8
#define P1_INIT 0
#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)
void coderZF_encodeBand(coder *me,int *band,int w,int h,int fullw,int *parent);
void coderZF_decodeBand(coder *me,int *band,int w,int h,int fullw,int *parent);
typedef struct {
int signs_p0[SIGN_CONTEXTS];
int signs_pt[SIGN_CONTEXTS];
int stats_p0[NUM_CONTEXTS];
int stats_pt[NUM_CONTEXTS];
int tails_p0[TAIL_CONTEXTS];
int tails_pt[TAIL_CONTEXTS];
} myInfo;
void coderZF_init(coder *c)
{
myInfo *d;
int i;
if ( (d = new(myInfo)) == NULL )
errexit("ozero init failed");
c->data = d;
for(i=0;i<NUM_CONTEXTS;i++) {
d->stats_p0[i] = P0_INIT+1; d->stats_pt[i] = 2+P0_INIT+P1_INIT;
}
for(i=0;i<SIGN_CONTEXTS;i++) {
d->signs_p0[i] = 100;
d->signs_pt[i] = 200;
}
for(i=0;i<TAIL_CONTEXTS;i++) {
d->tails_p0[i] = 100;
d->tails_pt[i] = 2000;
}
}
void coderZF_free(coder *c)
{
if ( c->data ) {
myInfo *d;
d = c->data;
free(d);
c->data = NULL;
}
}
coder coderZF = {
"ZeroFlag",
coderZF_init,
coderZF_free,
coderZF_encodeBand,
coderZF_decodeBand
};
static int sign_context; /** cheesy way to return two values **/
static int mcontext(int *dp,int x,int y,int fullw)
{
if ( y == 0 ) {
if ( x > 0 ) {
int W;
W = dp[-1];
if ( isneg(W) ) { sign_context = 2; W = - W; }
else sign_context =0;
return min(VAL_CONTEXT_MAX, (W>>1));
} else {
sign_context = 0 ;
return 0;
}
} else if ( x == 0 ) {
int N;
N = dp[-fullw];
if ( isneg(N) ) { sign_context = 1; N = - N; }
else sign_context = 0;
return min(VAL_CONTEXT_MAX, (N>>1));
} else {
int N,W;
N = dp[-fullw];
W = dp[-1];
if ( isneg(N) ) { sign_context = 1; N = - N; }
else sign_context = 0;
if ( isneg(W) ) { sign_context += 2; W = - W; }
return min(VAL_CONTEXT_MAX, ((N + W)>>2));
}
}
void coderZF_encodeBand(coder *me,int *band,int width,int height,int fullw,int *parent)
{
int x,y,context,V;
int *dp;
arithInfo *ari;
int *signs_p0,*signs_pt;
int *tails_p0,*tails_pt;
int *stats_p0,*stats_pt;
ari = me->arith;
stats_p0 = ((myInfo *)me->data)->stats_p0;
stats_pt = ((myInfo *)me->data)->stats_pt;
signs_p0 = ((myInfo *)me->data)->signs_p0;
signs_pt = ((myInfo *)me->data)->signs_pt;
tails_p0 = ((myInfo *)me->data)->tails_p0;
tails_pt = ((myInfo *)me->data)->tails_pt;
dp = band;
for(y=0;y<height;y++) {
if ( coder_timetostop(me) ) { coder_didstop(me,y); return; }
for(x=0;x<width;x++) {
context = mcontext(dp+x,x,y,fullw);
if ( (V=dp[x]) == 0 ) {
bitEnc(0,ari,stats_p0[context],stats_pt[context]);
} else {
bitEnc(1,ari,stats_p0[context],stats_pt[context]);
switch(V) {
case 4:
bitEnc(0,ari,signs_p0[sign_context],signs_pt[sign_context]);
bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(0,ari,tails_p0[context],tails_pt[context]);
break;
case 3:
bitEnc(0,ari,signs_p0[sign_context],signs_pt[sign_context]);
bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(0,ari,tails_p0[context],tails_pt[context]);
break;
case 2:
bitEnc(0,ari,signs_p0[sign_context],signs_pt[sign_context]);
bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(0,ari,tails_p0[context],tails_pt[context]);
break;
case 1:
bitEnc(0,ari,signs_p0[sign_context],signs_pt[sign_context]);
bitEnc(0,ari,tails_p0[context],tails_pt[context]);
break;
case 0:
break;
case -1:
bitEnc(1,ari,signs_p0[sign_context],signs_pt[sign_context]);
bitEnc(0,ari,tails_p0[context],tails_pt[context]);
break;
case -2:
bitEnc(1,ari,signs_p0[sign_context],signs_pt[sign_context]);
bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(0,ari,tails_p0[context],tails_pt[context]);
break;
case -3:
bitEnc(1,ari,signs_p0[sign_context],signs_pt[sign_context]);
bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(0,ari,tails_p0[context],tails_pt[context]);
break;
case -4:
bitEnc(1,ari,signs_p0[sign_context],signs_pt[sign_context]);
bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(0,ari,tails_p0[context],tails_pt[context]);
break;
default:
if ( V > 0 ) {
bitEnc(0,ari,signs_p0[sign_context],signs_pt[sign_context]);
V--;
} else {
bitEnc(1,ari,signs_p0[sign_context],signs_pt[sign_context]);
V = - V -1;
}
/* send remainder */
while(V--) bitEnc(1,ari,tails_p0[context],tails_pt[context]);
bitEnc(0,ari,tails_p0[context],tails_pt[context]);
break;
}
}
}
dp += fullw;
}
}
void coderZF_decodeBand(coder *me,int *band,int width,int height,int fullw,int *parent)
{
int x,y,bit,sign,context,V;
int *dp;
arithInfo *ari;
int *signs_p0,*signs_pt;
int *stats_p0,*stats_pt;
int *tails_p0,*tails_pt;
ari = me->arith;
stats_p0 = ((myInfo *)me->data)->stats_p0;
stats_pt = ((myInfo *)me->data)->stats_pt;
signs_p0 = ((myInfo *)me->data)->signs_p0;
signs_pt = ((myInfo *)me->data)->signs_pt;
tails_p0 = ((myInfo *)me->data)->tails_p0;
tails_pt = ((myInfo *)me->data)->tails_pt;
dp = band;
for(y=0;y<height;y++) {
if ( coder_timetostopd(me,y) ) return;
for(x=0;x<width;x++) {
context = mcontext(dp+x,x,y,fullw);
bitDec(bit,ari,stats_p0[context],stats_pt[context]);
if ( bit == 0 ) {
dp[x] = 0;
} else {
bitDec(sign,ari,signs_p0[sign_context],signs_pt[sign_context]);
bitDec(bit,ari,tails_p0[context],tails_pt[context]);
if ( !bit ) {
dp[x] = (1 - sign - sign);
} else {
bitDec(bit,ari,tails_p0[context],tails_pt[context]);
if ( !bit ) {
if ( sign ) dp[x] = -2; else dp[x] = 2;
} else {
bitDec(bit,ari,tails_p0[context],tails_pt[context]);
if ( !bit ) {
if ( sign ) dp[x] = -3; else dp[x] = 3;
} else {
bitDec(bit,ari,tails_p0[context],tails_pt[context]);
if ( !bit ) {
if ( sign ) dp[x] = -4; else dp[x] = 4;
} else {
V = 4;
do {
V++;
bitDec(bit,ari,tails_p0[context],tails_pt[context]);
} while( bit == 1 );
if ( sign ) dp[x] = -V; else dp[x] = V;
}
}
}
}
}
}
dp += fullw;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -