?? coder_o1_sb.c
字號:
/*********
Order1 SB : context-code MSB position like order1+1 ,
then code residual bits.
(o1_sb is good on 'circles' and golf data;
competitive with bitplane and order2)
S+P (512) Lossless :
Lena Zelda Kuha Checa(256)
Order1 : 4.250 3.948 3.534 3.406
Order1+1: 4.207 3.911 3.517 3.310
Order1sb: 4.216 3.920 3.510 3.305
We seem to beat 1+1 on the very-compressible files, while
we lose on the less compressible files (though this is not
a uniform trend; for example we have identical performance
on Barbara at 4.678 bpp)
SB seams to always beat 1+1 slightly on non-lossless packing,
but this is a moot point because BitPlane stomps them both
for lossy; (bitplane is behind even plain order1 for lossless;
very strange)
(bitplane on the lossy and order1+1 on the deltas is the best
for lossy+delta , but that's again moot because S+P stomps
on lossy+delta).
**********/
#include <stdio.h>
#include <stdlib.h>
#include <crblib/inc.h>
#include <crblib/arithc.h>
#include <crblib/scontext.h>
#include <crblib/intmath.h>
extern int tune_param;
#define ORDER1_TOTMAX 10000
#define ORDER1_INC 30
#define ORDER1_RAWS 2
#define ORDER1_ALPHABET (16 + ORDER1_RAWS) /** # of bits **/
#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 16000 /** totally irrelevant **/
#define ORDER0_ALPHABET 2 /** binary **/
#define ORDER0_INC 10
// #define CODER_ADAPT /** doesn't help **/
#include "coder.h"
void coderO1_SB_encodeBand(coder *me,int *band,int w,int h,int fullw,int *parent);
void coderO1_SB_decodeBand(coder *me,int *band,int w,int h,int fullw,int *parent);
typedef struct {
scontext * o0;
scontext * sign_sc[3];
scontext ** o1;
arithInfo *ari;
} myInfo;
void coderO1_SB_init(coder *c)
{
myInfo *d;
int i;
if ( (d = new(myInfo)) == NULL )
errexit("ozero init failed");
c->data = d;
d->ari = c->arith;
if ( (d->o0 = scontextCreate(c->arith,ORDER0_ALPHABET,0,
ORDER0_TOTMAX,ORDER0_INC,true)) == 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_SB_free(coder *c)
{
if ( c->data ) {
myInfo *d; int i;
d = c->data;
if ( d->o0 ) scontextFree(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_SB = {
"SigBit",
coderO1_SB_init,
coderO1_SB_free,
coderO1_SB_encodeBand,
coderO1_SB_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));
}
static void encode_val(myInfo *mi,int sym,int context)
{
if ( sym < ORDER1_RAWS ) {
scontextEncode(mi->o1[context],sym);
} else {
int bits,msb;
sym -= (ORDER1_RAWS-1); /** can't use zero **/
bits = intlog2(sym);
msb = (1<<bits);
sym -= msb;
scontextEncode(mi->o1[context],bits+ORDER1_RAWS);
/** sym < msb now **/
msb>>=1;
for(;msb>=1;msb>>=1) {
scontextEncode(mi->o0,(sym&msb)?1:0);
}
}
}
static int decode_val(myInfo *mi,int bits,int context)
{
if ( bits < ORDER1_RAWS ) {
return bits;
} else {
int msb,sym,top;
bits -= ORDER1_RAWS;
msb = 1<<bits;
sym = 0;
for(top = msb>>1;top>=1;top>>=1) {
if ( scontextDecode(mi->o0) ) sym += top;
}
sym += msb + ORDER1_RAWS - 1;
return sym;
}
}
static void coder_scaledown(myInfo *mi)
{
int i;
scontextHalve(mi->o0);
for(i=0;i<3;i++)
scontextHalve(mi->sign_sc[i]);
for(i=0;i<CODE_CONTEXTS;i++)
scontextHalve(mi->o1[i]);
}
void coderO1_SB_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;
myInfo *mi = ((myInfo *)me->data);
scontext **sign_sc = ((myInfo *)me->data)->sign_sc;
scontext **o1 = ((myInfo *)me->data)->o1;
#ifdef CODER_ADAPT
coder_scaledown(mi);
#endif
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;
}
encode_val(mi,val,cntx);
scontextEncode(sign_sc[sign_cntx],sign);
}
if ( y & 1 ) pp += fullw;
dp += fullw;
}
}
void coderO1_SB_decodeBand(coder *me,int *band,int width,int height,int fullw,int *parent)
{
int x,y,val,cntx,sign_cntx;
int *dp,*pp,*dpp,*ppp;
myInfo *mi = ((myInfo *)me->data);
scontext **sign_sc = ((myInfo *)me->data)->sign_sc;
scontext **o1 = ((myInfo *)me->data)->o1;
#ifdef CODER_ADAPT
coder_scaledown(mi);
#endif
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++;
val = scontextDecode(o1[cntx]);
if ( val == 0 ) {
*dpp++ = 0;
continue;
}
val = decode_val(mi,val,cntx);
if ( scontextDecode(sign_sc[sign_cntx]) ) val = -val;
*dpp++ = val;
}
if ( y & 1 ) pp += fullw;
dp += fullw;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -