?? coder_bp_sorted.c
字號:
/*****
same as the plain old EZ coder_bp.c but we send the quartets in order
of their parents' magnitude.
sorting usually HURTS compression !?
I thought it would help & mean that TOTMAX could be lower, and the
parent could be taken out of the context.
sorting *does* help some when we stop early, about 0.1 PSNR or 0.05 RMSE
but even this isn't always the case (!)
happily the qsort() is blazing fast and hardly hurts time significantly
*****/
#include <stdio.h>
#include <stdlib.h>
#include <crblib/inc.h>
#include <crblib/arithc.h>
#include <crblib/scontext.h>
extern int tune_param;
#define ORDER1_CONTEXTS 10
#define ORDER1_ALPHABET 16 //4 bits
#define ORDER1_TOTMAX 14000
#define ORDER1_INC 30
#include "coder.h"
void coderBPsorted_encodeBandBP(coder *me,int *band,int w,int h,int fullw,int *parent,int);
void coderBPsorted_decodeBandBP(coder *me,int *band,int w,int h,int fullw,int *parent,int);
typedef struct {
scontext ** o1;
} myInfo;
void coderBPsorted_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!");
}
}
void coderBPsorted_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 coderBPsorted = {
"BP sorted",
coderBPsorted_init,
coderBPsorted_free,
NULL,NULL,
coderBPsorted_encodeBandBP,
coderBPsorted_decodeBandBP
};
typedef struct {
int parent;
int *blockptr;
} sortType;
int sortTypeCmp(const void * s1,const void *s2)
{
int ret = (((sortType *)s2)->parent - ((sortType *)s1)->parent );
if ( ret == 0 ) {
ret = (int)(((sortType *)s2)->blockptr - ((sortType *)s1)->blockptr );
}
return ret;
}
void coderBPsorted_encodeBandBP(coder *me,int *band,int width,int height,int fullw,int *parent,int bitmask)
{
int x,y; //,val,cntx;
int *dp,*pp,*dpn;
int context,block,A,B,C,D,nparents;
scontext **o1 = ((myInfo *)me->data)->o1;
arithInfo *ari = me->arith;
int donemask,nextmask;
sortType *sortBlock,*sortPtr;
for(x= bitmask,nextmask=0; x<CODE_MAX_VAL ;x+=x) nextmask += x;
donemask = nextmask - bitmask;
// load in the sortBlock
nparents = (height*width)>>2;
if ( (sortBlock = newarray(sortType,nparents)) == NULL )
{ coder_didstop(me,0); return; }
sortPtr = sortBlock;
for(y=0;y<height;y+=2) {
dp = band + y*fullw;
pp = parent + (y>>1)*fullw;
for(x=0;x<width;x+=2) { /** x & y are the parent's location *2 **/
sortPtr->parent = abs(*pp) & nextmask;
sortPtr->blockptr = dp;
sortPtr++; pp++; dp += 2;
}
}
qsort((void *)sortBlock,nparents,sizeof(sortType),sortTypeCmp);
sortPtr = sortBlock;
for(x=0;x<nparents;x++) {
if ( coder_timetostop(me) ) { coder_didstop(me,x); return; }
dp = sortPtr->blockptr; dpn = dp + fullw;
A = abs(dp[0]); B = abs(dp[1]);
C = abs(dpn[0]); D = abs(dpn[1]);
context = ((A & donemask)?1:0) + ((B & donemask)?1:0) + ((C & donemask)?1:0) + ((D & donemask)?1:0);
if ( sortPtr->parent ) context += 5;
block = 0; // 4 bits
if ( A & bitmask ) block += 1;
if ( B & bitmask ) block += 2;
if ( C & bitmask ) block += 4;
if ( D & bitmask ) block += 8;
scontextEncode(o1[context],block);
/** send signs when we see the first 'on' bit **/
if ( (A & nextmask) == bitmask ) arithBit(ari, signbit(dp[0]) );
if ( (B & nextmask) == bitmask ) arithBit(ari, signbit(dp[1]) );
if ( (C & nextmask) == bitmask ) arithBit(ari, signbit(dpn[0]));
if ( (D & nextmask) == bitmask ) arithBit(ari, signbit(dpn[1]));
sortPtr++;
}
free(sortBlock);
}
void coderBPsorted_decodeBandBP(coder *me,int *band,int width,int height,int fullw,int *parent,int bitmask)
{
int x,y; //,val,cntx,sign;
int *dp,*pp,*dpn;
//int top_val,top_bitpn;
int context,block,A,B,C,D;
scontext **o1 = ((myInfo *)me->data)->o1;
arithInfo *ari = me->arith;
int donemask,nextmask,nparents;
sortType *sortBlock,*sortPtr;
for(x= bitmask,nextmask=0; x<CODE_MAX_VAL ;x+=x) nextmask += x;
donemask = nextmask - bitmask;
// load in the sortBlock
nparents = (height*width)>>2;
if ( (sortBlock = newarray(sortType,nparents)) == NULL )
return;
sortPtr = sortBlock;
for(y=0;y<height;y+=2) {
dp = band + y*fullw;
pp = parent + (y>>1)*fullw;
for(x=0;x<width;x+=2) { /** x & y are the parent's location *2 **/
sortPtr->parent = abs(*pp) & nextmask;
sortPtr->blockptr = dp;
sortPtr++; pp++; dp += 2;
}
}
qsort((void *)sortBlock,nparents,sizeof(sortType),sortTypeCmp);
// read it out
sortPtr = sortBlock;
for(x=0;x<nparents;x++) {
if ( coder_timetostopd(me,x) ) return;
dp = sortPtr->blockptr; dpn = dp + fullw;
A = abs(dp[0]); B = abs(dp[1]);
C = abs(dpn[0]); D = abs(dpn[1]);
context = ((A & donemask)?1:0) + ((B & donemask)?1:0) + ((C & donemask)?1:0) + ((D & donemask)?1:0);
if ( sortPtr->parent ) context += 5;
block = scontextDecode(o1[context]);
if ( block & 1 ) {
if ( !A ) dp[0] = arithGetBit(ari)? -bitmask: bitmask;
else if ( isneg(dp[0]) ) dp[0] -= bitmask; else dp[0] += bitmask;
}
if ( block & 2 ) {
if ( !B ) dp[1] = arithGetBit(ari)? -bitmask: bitmask;
else if ( isneg(dp[1]) ) dp[1] -= bitmask; else dp[1] += bitmask;
}
if ( block & 4 ) {
if ( !C ) dpn[0] = arithGetBit(ari)? -bitmask: bitmask;
else if ( isneg(dpn[0]) ) dpn[0] -= bitmask; else dpn[0] += bitmask;
}
if ( block & 8 ) {
if ( !D ) dpn[1] = arithGetBit(ari)? -bitmask: bitmask;
else if ( isneg(dpn[1]) ) dpn[1] -= bitmask; else dpn[1] += bitmask;
}
sortPtr++;
}
free(sortBlock);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -