📄 endecode.cpp
字号:
ptr1 = LSP_ptr1[LSP_idx] = image.address1(nc);
*ptr = (b & m ? -act_value : act_value);
if(mdc==1||last_mark) *ptr1 = *ptr; //保存描述1的内容到coeff1
m <<= 1; }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Desc_Test(Tree_Node * act_node)
{//输出Sn(D),有非零子孙,则把该项从LIS摘除,其子节点挂到LISP并输出Sn,非零子节点LIP->LSP
Image_Coord pc = act_node->coord;
//输出Sn(D),并返回是否有非零子孙标志
int st_trans = Desc_Transition(int(act_node->state & 0xFFL), pc);
if (!st_trans) return;
//有非零子孙,进一步处理
act_node->state |= st_trans; st_trans >>= 1;
Tree_Node * new_node;
long ns = (act_node->state & 0xFF00L) - 0x200L;//子树的状态
if (ns < 0x300L) ns |= 0xAAL; //最后一层处理结束
int root = ((act_node->state & 0xFF00L) >= root_code);//LL子带标志
for (int i = 0; i < 4; i++, st_trans >>= 2)
if (st_trans & 0x1) {//该节点有非零子孙,把儿子节点挂到LISP队列
NEW_OBJECT(new_node, Tree_Node, "LISP entry");
if (root) {//LL子带
if (i == 3) ns -= 0x100L;
new_node->coord.x = pc.x + SHF_x[i] * root_dim.x;
new_node->coord.y = pc.y + SHF_y[i] * root_dim.y; }
else {
new_node->coord.x = (pc.x + SHF_x[i]) << 1;
new_node->coord.y = (pc.y + SHF_y[i]) << 1; }
new_node->next = NULL; new_node->state = ns;
LISP_end->next = new_node; LISP_end = new_node;
Node_Test(new_node); }//输出node中各Sn。若有系数>门限,输出该系数的符号,并移出LIP表放入LSP
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DeDesc_Test(Tree_Node * act_node)
{//输出Sn(D),有非零子孙,则把该项从LIS摘除,其子节点挂到LISP并输出Sn,非零子节点LIP->LSP
Image_Coord pc = act_node->coord;
//输出Sn(D),并返回是否有非零子孙标志
int st_trans = DeDesc_Transition(int(act_node->state & 0xFFL), pc);
if (!st_trans) return;
//有非零子孙,进一步处理
act_node->state |= st_trans; st_trans >>= 1;
Tree_Node * new_node;
long ns = (act_node->state & 0xFF00L) - 0x200L;//子树的状态
if (ns < 0x300L) ns |= 0xAAL; //最后一层处理结束
int root = ((act_node->state & 0xFF00L) >= root_code);//LL子带标志
for (int i = 0; i < 4; i++, st_trans >>= 2)
if (st_trans & 0x1) {//该节点有非零子孙,把儿子节点挂到LISP队列
NEW_OBJECT(new_node, Tree_Node, "LISP entry");
if (root) {//LL子带
if (i == 3) ns -= 0x100L;
new_node->coord.x = pc.x + SHF_x[i] * root_dim.x;
new_node->coord.y = pc.y + SHF_y[i] * root_dim.y; }
else {
new_node->coord.x = (pc.x + SHF_x[i]) << 1;
new_node->coord.y = (pc.y + SHF_y[i]) << 1; }
new_node->next = NULL; new_node->state = ns;
LISP_end->next = new_node; LISP_end = new_node;
DeNode_Test(new_node); }//输出node中各Sn。若有系数>门限,输出该系数的符号,并移出LIP表放入LSP
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Node_Transition(int old_st, const Image_Coord & pc, int * signs)
{
int st_trans = 0, os = old_st, ps = old_st, mask = 1/*处理LIP表*/, i;
int msk[3], count[4];
for (i = 0; i < 4; i++) count[i] = 0;//LIS+LIP;LIS+LSP;LIP;LSP
for (i = 0; i < 4; i++, ps >>= 2) ++count[ps&0x3];//计算不同状态树的个数
msk[0] = msk[1] = 1; msk[2] = 1 << count[0];//低位存LIS+LIP项,每项占1位,高位存LIP项
int mod = count[2] - count[0] * count[1] - 1 + //选择算术编码模式
(count[0] * (count[0] * (count[0] - 18) + 107)) / 6 +
(count[1] * (11 - count[1])) / 2;
int b = 0;//初始化非零标志Sn
for (*signs = i = 0; i < 4; i++, mask <<= 2, os >>= 2) {//LIP队列处理
if (old_st & mask) continue; //LSP项,不处理
ps = os & 0x3;
if (ABS(image(pc.x + SHF_x[i], pc.y + SHF_y[i])) >= threshold) {
b |= msk[ps];//LIS存低位,非LIS存高位
st_trans |= mask; ++(*signs); }//置LIP->LSP的标志和个数
msk[ps] <<= 1; }
data_file.code_symbol(b, node_model[mod]);
return st_trans;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int DeNode_Transition(int old_st, const Image_Coord & pc, int * signs)
{
int st_trans = 0, os = old_st, ps = old_st, mask = 1/*处理LIP表*/, i;
int msk[3], count[4];
for (i = 0; i < 4; i++) count[i] = 0;//LIS+LIP;LIS+LSP;LIP;LSP
for (i = 0; i < 4; i++, ps >>= 2) ++count[ps&0x3];//计算不同状态树的个数
msk[0] = msk[1] = 1; msk[2] = 1 << count[0];//低位存LIS+LIP项,每项占1位,高位存LIP项
int mod = count[2] - count[0] * count[1] - 1 + //选择算术编码模式
(count[0] * (count[0] * (count[0] - 18) + 107)) / 6 +
(count[1] * (11 - count[1])) / 2;
int b = dedata_file.decode_symbol(node_model[mod]);
for (*signs = i = 0; i < 4; i++, mask <<= 2, os >>= 2) {//LIP队列处理
if (old_st & mask) continue; //LSP项,不处理
ps = os & 0x3;
if (b & msk[ps]) {
st_trans |= mask; ++(*signs); }//置LIP->LSP的标志和个数
msk[ps] <<= 1; }
return st_trans;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Desc_Transition(int old_st, const Image_Coord & pc)
{//输出Sn(D),若有非零子孙,返回标志
int os = old_st, ps = os, st_trans = 0, mask = 2/*处理LIS*/, i;
int msk[3], count[4];
for (i = 0; i < 4; i++) count[i] = 0;
for (i = 0; i < 4; i++, ps >>= 2) ++count[ps & 0x3];
msk[0] = 1; msk[1] = msk[2] = 1 << count[0];//低位存LIS+LIP项,每项占1位,高位存LIS项
int mod = count[2] - count[0] * count[1] - 1 +
(count[0] * (count[0] * (count[0] - 18) + 107)) / 6 +
(count[1] * (11 - count[1])) / 2;
int b = 0;
for (i = 0; i < 4; i++, mask <<= 2, os >>= 2) {
if (old_st & mask) continue;
ps = os & 0x3;
if (max_image(pc.x + SHF_x[i], pc.y + SHF_y[i]) >= threshold) {//有非零子孙Sn(D)=1
b |= msk[ps];
st_trans |= mask; }
msk[ps] <<= 1; }//指向下一个位置
if ((old_st & 0xAA) == 0) {//四个均为LIS
data_file.code_symbol(st_trans == 0, group_model[count[0]]);//可视为输出Sn(L)
if (st_trans == 0) return 0; }
data_file.code_symbol(b, desc_model[mod]);
return st_trans;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int DeDesc_Transition(int old_st, const Image_Coord & pc)
{//输出Sn(D),若有非零子孙,返回标志
int os = old_st, ps = os, st_trans = 0, mask = 2/*处理LIS*/, i;
int msk[3], count[4];
for (i = 0; i < 4; i++) count[i] = 0;
for (i = 0; i < 4; i++, ps >>= 2) ++count[ps & 0x3];
msk[0] = 1; msk[1] = msk[2] = 1 << count[0];//低位存LIS+LIP项,每项占1位,高位存LIS项
int mod = count[2] - count[0] * count[1] - 1 +
(count[0] * (count[0] * (count[0] - 18) + 107)) / 6 +
(count[1] * (11 - count[1])) / 2;
if ((old_st & 0xAA) == 0)
if (dedata_file.decode_symbol(group_model[count[0]])) return 0;
int b = dedata_file.decode_symbol(desc_model[mod]);
for (i = 0; i < 4; i++, mask <<= 2, os >>= 2) {
if (old_st & mask) continue;
ps = os & 0x3;
if (b & msk[ps]) {
st_trans |= mask; }
msk[ps] <<= 1; }//指向下一个位置
return st_trans;
}
// - - Lossy version functions - - - - - - - - - - - - - - - - - - - - -
void Node_Test(Tree_Node * act_node)
{//若node中有IP项,输出Sn。若有系数>门限,输出该系数的符号,并移出LIP表放入LSP
int st_trans, signs;
st_trans = Node_Transition(int(act_node->state & 0xFFL),
act_node->coord, &signs);//若node中有IP项,输出Sn。若有系数>门限,移出LIP表
if (st_trans) {//若有系数>门限,输出该系数的符号,并放入LSP
act_node->state |= long(st_trans);
Output_Signs(signs, st_trans, act_node->coord); }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DeNode_Test(Tree_Node * act_node)
{
int st_trans, signs;
st_trans = DeNode_Transition(int(act_node->state & 0xFFL),
act_node->coord, &signs);
if (st_trans) {
act_node->state |= long(st_trans);
DeOutput_Signs(signs, st_trans, act_node->coord); }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
boolean Refinement_Pass(void)
{
int b, p, m, n = LSP_plane, k = LSP_dim.y;
double * ptr, * smk, ** mtx = LSP_mtx[0];
LSP_mark[LSP_plane++] = (LSP_ptr ? LSP_ptr[LSP_idx] : 0);
for (m = p = 0; p < n; p++) {
for (smk = LSP_mark[p], ptr = 0; ptr != smk;) {
if (!k) {
mtx = LSP_mtx[++m]; k = LSP_dim.y; }
ptr = mtx[--k];
if (b = (*ptr >= threshold)) *ptr -= threshold;
data_file.code_bit(b);
if (data_file.bytes_used() >= byte_budget) return true; } }
return false;
}
//----------------------------------------------------------------------
boolean DeRefinement_Pass(void)
{
double t, ht1, ht2;
int b, p, m, n = LSP_plane, k = LSP_dim.y;
double * ptr, * smk, ** mtx = LSP_mtx[0];
double *ptr1, ** mtx1 = LSP_mtx1[0];
LSP_mark[LSP_plane++] = (LSP_ptr ? LSP_ptr[LSP_idx] : 0);
for (m = p = 0; p < n; p++) {
t = bias[p];
bias[p] = threshold * (0.5 - 0.25 / Sqr(LSP_plane - p));
ht1 = bias[p] - t; ht2 = ht1 + threshold;
for (smk = LSP_mark[p], ptr = 0; ptr != smk;) {
if (!k) {
mtx = LSP_mtx[++m]; mtx1 = LSP_mtx1[m]; k = LSP_dim.y; }
ptr = mtx[--k]; ptr1 = mtx1[k];
t = (dedata_file.decode_bit() ? ht2 : ht1);
if (*ptr > 0) {
*ptr += t;
if (mdc==1) *ptr1 += t; } //只有描述1写入coeff1
else {
*ptr -= t;
if (mdc==1) *ptr1 -= t; }
if (dedata_file.bytes_used() >= byte_budget) return true; } }
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void final_bit()
{
int b, p, m, n = LSP_plane, k = LSP_dim.y, ss=mdc-1;
double * ptr, * smk, ** mtx = LSP_mtx[0];
LSP_mark[LSP_plane++] = (LSP_ptr ? LSP_ptr[LSP_idx] : 0);
for (m = p = 0; p < n; p++) {
for (smk = LSP_mark[p], ptr = 0; ptr != smk;) {
if (!k) {
mtx = LSP_mtx[++m]; k = LSP_dim.y; }
ptr = mtx[--k];
b = (*ptr >= threshold);
if (!ss) data_file.code_bit(b); }
ss^=1; }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Definal_bit(void)
{
double t, ht1, ht2;
int p, m, n = LSP_plane, k = LSP_dim.y;
int ss=mdc-1;
double * ptr, * smk, ** mtx = LSP_mtx[0];
double * ptr1, **mtx1 = LSP_mtx1[0];
LSP_mark[LSP_plane++] = (LSP_ptr ? LSP_ptr[LSP_idx] : 0);
for (m = p = 0; p < n; p++) {
t = bias[p];
bias[p] = threshold * (0.5 - 0.25 / Sqr(LSP_plane - p));
ht1 = bias[p] - t; ht2 = ht1 + threshold;
for (smk = LSP_mark[p], ptr = 0; ptr != smk;) {
if (!k) {
mtx = LSP_mtx[++m]; k = LSP_dim.y;
mtx1 = LSP_mtx1[m];}
ptr = mtx[--k]; ptr1 = mtx1[k];
if (!ss) {
t = (dedata_file.decode_bit() ? ht2 : ht1);
if (*ptr > 0) {*ptr += t; *ptr1 += t; }
else {*ptr -= t; *ptr1 -= t; }}}
ss^=1;}
}
// - - Encoder functions - - - - - - - - - - - - - - - - - - - - - - - -
Pel_Type Max_Desc_Val(int l, int s, int x, int y)
{
Pel_Type t, m = 0;
Image_Coord ds;
--l; --s;
for (int d = 0; d < 4; d++) {
ds.x = x + SHF_x[d]; ds.y = y + SHF_y[d];
t = Magn_Val(image[ds], s);
if (m < t) m = t;
if (l > 0) {
max_image[ds] = t = Max_Desc_Val(l, s, ds.x << 1, ds.y << 1);
if (m < t) m = t; } }
return m;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Calc_Max_Image(void)
{
Image_Coord tc, pc = image.dimension(), lm = pc;
int i, sd, lv = image.pyramid_levels(), sp = lv + 1;
Pel_Type t, max = 0;
lm.x >>= lv; lm.y >>= lv; pc.x >>= 1; pc.y >>= 1;
max_image.reset(pc, 0);
for (pc.x = 0; pc.x < lm.x; pc.x += 2)
for (pc.y = 0; pc.y < lm.y; pc.y += 2) {
t = max_image[pc] = Magn_Val(image[pc], sp);
if (max < t) max = t;
for (sd = sp, i = 1; i < 4; i++) {
tc.x = pc.x + SHF_x[i]; tc.y = pc.y + SHF_y[i];
t = Magn_Val(image[tc], sp);
if (max < t) max = t;
if (i == 3) --sd;
t = max_image[tc] = Max_Desc_Val(lv, sd,
pc.x + SHF_x[i] * lm.x, pc.y + SHF_y[i] * lm.y);
if (max < t) max = t; } }
return int(log(max) / log(2.0));
}
//---------------------------------------------------------------------
void all_phase_motion_Estimation(Image_Coord dimension, Pel_Type ** Pcoeff, Pel_Type ** Pcoeff2) //double
{
int i, j, i0, j0, dx, dy, i2, j2, i1, j1;
int x, y, dx1, dy1, W = 8;//搜索窗口大小
int Width=dimension.y,Height=dimension.x;
double sad, smin;
// char c1;
/* FILE *mvfile;
mvfile = fopen(mp, "wb");
if(!mvfile) {
cout<<"cannot open mvfile1"<<endl;
exit(-1);
}*/
//------------- Do motion estimation and store result in array
for ( y=0, j=0; y<Height; j++, y+=16) {//最大子带每块8x8,全相分解变成16x16
for ( x=0, i=0; x<Width; i++, x+=16) {
smin = 665536; dx1=0; dy1=0;
for (dy=-W;dy<W;dy++) {
if (y+dy<0||y+dy+14>=Height) continue; //为什么要加14??????
for(dx=-W;dx<W;dx++) {
if(x+dx<0||x+dx+14>=Width) continue;
sad=0;
//求第1次分解(HL1, LH1, HH1)残差
i0 = x>>1; j0 = y>>1;
i1 = i0 + (Width>>1); j1 = j0 + (Height>>1);
for (j2=0; j2<8;j2++) {//计算最大子带中的残差
for (i2=0; i2<8; i2++) {
sad += fabs(Pcoeff[j0+j2][i1+i2]-w[0][0][y+dy+(j2<<1)][x+dx+(i2<<1)]);
sad += fabs(Pcoeff[j1+j2][i0+i2]-w[0][1][y+dy+(j2<<1)][x+dx+(i2<<1)]);
sad += fabs(Pcoeff[j1+j2][i1+i2]-w[0][2][y+dy+(j2<<1)][x+dx+(i2<<1)]);
}
}
i0>>=1; j0>>=1; i1>>=1; j1>>=1;
for (j2=0; j2<4; j2++) {//计算中间子带中的残差
for (i2=0; i2<4; i2++) {
sad += fabs(Pcoeff[j0+j2][i1+i2]-w[1][0][y+dy+(j2<<2)][x+dx+(i2<<2)]);
sad += fabs(Pcoeff[j1+j2][i0+i2]-w[1][1][y+dy+(j2<<2)][x+dx+(i2<<2)]);
sad += fabs(Pcoeff[j1+j2][i1+i2]-w[1][2][y+dy+(j2<<2)][x+dx+(i2<<2)]);
}
}
i0>>=1; j0>>=1; i1>>=1; j1>>=1;
for (j2=0; j2<2; j2++) {//计算最小子带中的残差
for (i2=0; i2<2; i2++) {
sad += fabs(Pcoeff[j0+j2][i0+i2]-w1[0][0][y+dy+(j2<<3)][x+dx+(i2<<3)]);
sad += fabs(Pcoeff[j0+j2][i1+i2]-w1[0][1][y+dy+(j2<<3)][x+dx+(i2<<3)]);
sad += fabs(Pcoeff[j1+j2][i0+i2]-w1[1][0][y+dy+(j2<<3)][x+dx+(i2<<3)]);
sad += fabs(Pcoeff[j1+j2][i1+i2]-w1[1][1][y+dy+(j2<<3)][x+dx+(i2<<3)]);
}
}
if (sad < smin) {
dx1=dx; dy1=dy;
smin=sad;
}
}
}
dx = dx1; dy = dy1;
for (j2=0; j2<2; j2++) {//计算最小子带中的参考图像块
for (i2=0; i2<2; i2++) {
Pcoeff2[j0+j2][i0+i2] = w1[0][0][y+dy+(j2<<3)][x+dx+(i2<<3)];
Pcoeff2[j0+j2][i1+i2] = w1[0][1][y+dy+(j2<<3)][x+dx+(i2<<3)];
Pcoeff2[j1+j2][i0+i2] = w1[1][0][y+dy+(j2<<3)][x+dx+(i2<<3)];
Pcoeff2[j1+j2][i1+i2] = w1[1][1][y+dy+(j2<<3)][x+dx+(i2<<3)];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -