?? modified_ebcot2.c
字號:
/******************************************************************************
功能描述:
Implements block_encode
以下部分是對EBCOT的編碼。三個通道。四種編碼形式
功能描述:編碼過程中,每個系數總處于三種狀態之一:無效態,有效態,上下文有效態
******************************************************************************/
/*****************************************************************************/
// 程序: ebcot 編碼
// 版本: V0.0
// 作者: 胡運平
// 最后修改時間 : 30, 6, 2005
/****************************************************************************/
#include <stdio.h>
#include<math.h>
#include<assert.h>
#include"fdwt.h"
#include"block_encode.h"
/******************************************************************************
//函數功能:
//輸入:1 3 7 15 31 63 127 255
//輸出 1 2 3 4 5 6 7 8
*******************************************************************************/
int log2i(int val)
{
int i;
if(val>=0 && val<=1)
i=0;
else if(val>=2 && val<=3)
i= 1;
else if(val>=4 && val<=7)
i =2;
else if(val>=8 && val<=15)
i=3;
else if(val>=16 && val<=31)
i=4;
else if(val>=32 && val<=63)
i=5;
else if(val>=64 && val<=127)
i=6;
else if(val>=128 && val<=255)
i=7;
return i;
}
/******************************************************************************
//輸入為block code 的小波量化系數,輸出為文件形式的(CX,D)
*******************************************************************************/
void block_encode(int block_bufferin[BLOCKLENGTH][BLOCKWIDTH])
{
int i,j,k,m;
int max;
unsigned char c[BLOCKLENGTH][BLOCKWIDTH];//顯著性狀態。
unsigned int f[BLOCKLENGTH][BLOCKWIDTH] = {0};
// unsigned char kign;
FILE *context;
if ((context = fopen("context.raw","wb+")) == NULL)
{
printf("cannot open file\n");
return;
}
/*******************************************************************************
// x;//符號變量
// q;//顯著性狀態變量
// e;//延遲顯著性狀態變量 表示系數是否是第一次被量值改進,也叫細化信息位
// v;//樣本比特值
// pi;//編碼狀態變量 ,在每個位平面P的第一編碼過程中設置其值,若該樣本在該編碼過程
//中處理,置1,否則設成0 初始化所有狀態變量為0
********************************************************************************/
for(i=0;i<BLOCKLENGTH;i++)
for(j=0;j<BLOCKWIDTH;j++)
{
state_data_x[i][j] = 0;
state_data_q[i][j] = 0;
state_data_e[i][j] = 0;
state_data_v[i][j] = 0;
state_data_pi[i][j] = 0;
}
/******************************************************************************
//小波系數的預處理,完成三個功能:碼塊生成過程,數據格式轉換過程,碼塊最大值查
找過程
//求單個碼塊的最大值和把符號位提取出來給符號變量X;符號變換,補碼形式變成源碼形式
*******************************************************************************/
max = abs(block_bufferin[0][0]);
for(i=0;i<BLOCKLENGTH;i++)
for(j=0;j<BLOCKWIDTH;j++)
{
state_data_x[i][j] = (block_bufferin[i][j]>>16 & 1);
block_bufferin[i][j] = abs(block_bufferin[i][j]);
if(block_bufferin[i][j]>max)
max = block_bufferin[i][j];
}
//環境狀態字初始化,16位,每一個總共表示有1個系數的所有狀態變量。
for(i=0;i<BLOCKLENGTH;i++)
for(j=0;j<BLOCKWIDTH;j++)
{
c[i][j] = 0;
}
/******************************************************************************
//預處理完畢可以進行下面的核心編碼操作,以四個系數作為一個stripe編碼,
//最高位平面開始編碼,最高位平面只進行cleanup通道編碼
//依次經過三個編碼通道。
//環境狀態字給初值,12位,顯示重要性狀態值。狀態變量如下所示:
// x;//符號變量
// q;//顯著性狀態變量
// e;//延遲顯著性狀態變量 表示系數是否是第一次被量值改進,也叫細化信息位
// v;//樣本比特值
// pi;//編碼狀態變量 表示位平面上的比特值是否已經被編碼,也叫訪問信息位
********************************************************************************/
for(k=log2i(max);k>-1;k--)
{//位平面層數,從最高位平面到最低位平面0編碼
for(i=0;i<BLOCKLENGTH;i++)
{
for(j=0;j<BLOCKWIDTH;j++)
{
c[i][j] = state_data_q[i][j];
state_data_v[i][j] = ((block_bufferin[i][j]>>k) & 1);
state_data_pi[i][j] = 0;
// printf("%d ",c[i][j]);
// printf("%d ",state_data[i][j].v);
// printf("%d ",state_data_x[i][j]);
// printf("%d ",block_bufferin[i][j]);
}
}
init_environment(f,c,state_data_x);
for(i=0;i<BLOCKLENGTH/4;i++)
{
for(j=0;j<BLOCKWIDTH;j++)
{
if(k==log2i(max))
goto RLC;
else
{
for(m=0;m<4;m++)
{//開始重要性傳播位平面的重要性掃描通道,處理當前不顯著,但具有顯著鄰域的樣本
if(state_data_q[4*i+m][j]==0 && init_significant(f[4*i+m][j],0)>0)
{//當前系數不是重要性系數,上下文區域不是0
fprintf(context,"%d %d ",init_significant(f[4*i+m][j],0),state_data_v[4*i+m][j]);
if(state_data_v[4*i+m][j])
{
state_data_q[4*i+m][j] = 1;
//unsigned char init_sign(unsigned int f, unsigned char v,int i,int j)
fprintf(context,"%d %d ",init_sign(f[4*i+m][j],state_data_x[4*i+m][j]),state_data_x[4*i+m][j]);
}
state_data_pi[4*i+m][j] = 1;
}
else
state_data_pi[4*i+m][j] = 0;
//開始幅值細化通過,位平面的幅度細化掃描通道
if(state_data_q[4*i+m][j]==1 && state_data_pi[4*i+m][j]==0)
{//該系數是重要的,
fprintf(context,"%d %d ",init_magnitude(f[4*i+m][j],state_data_e[4*i+m][j]),state_data_v[4*i+m][j]);
state_data_e[4*i+m][j] = 1;
}
}
//開始清除通過
RLC: if((init_significant(f[4*i][j],0)==0) && (init_significant(f[4*i+1][j],0)==0) &&
(init_significant(f[4*i+2][j],0)==0) && (init_significant(f[4*i+3][j],0)==0))
{
if(!(state_data_v[4*i][j] | state_data_v[4*i+1][j] |
state_data_v[4*i+2][j] | state_data_v[4*i+3][j]))
{
fprintf(context,"%d %d ",17,0);
// state_data_pi[4*i][j] = state_data_pi[4*i+1][j] =
// state_data_pi[4*i+2][j] = state_data_pi[4*i+3][j] = 1;
continue;
}
for(m = 0;m<4;m++)
{
if(state_data_v[4*i+m][j])
{
fprintf(context,"%d %d ",17,1);
if(m == 0)
{
fprintf(context,"%d %d ",18,0);
fprintf(context,"%d %d ",18,0);
//此時將符號位元編碼,有5種可能的情況(9-13)sign coding
// Encode sign bit
fprintf(context,"%d %d ",9,state_data_x[4*i+m][j]);
state_data_q[4*i+m][j] = 1;//重要性標志置1
// state_data_pi[4*i+m][j] = 1;//標志此位被訪問過。
//第二位開始編碼
fprintf(context,"%d %d ",0,state_data_v[4*i+m+1][j]);
// state_data_pi[4*i+m+1][j] = 1;//標志此位被訪問過。
if(state_data_v[4*i+m+1][j])
{
//此時將符號位元編碼,有5種可能的情況(9-13)sign coding
// Encode sign bit
fprintf(context,"%d %d ",9,state_data_x[4*i+m+1][j]);
state_data_q[4*i+m+1][j] = 1;//重要性標志置1
}
//第三位開始編碼
fprintf(context,"%d %d ",0,state_data_v[4*i+m+2][j]);
// state_data_pi[4*i+m+2][j] = 1;//標志此位被訪問過。
if(state_data_v[4*i+m+2][j])
{
//此時將符號位元編碼,有5種可能的情況(9-13)sign coding
// Encode sign bit
fprintf(context,"%d %d ",9,state_data_x[4*i+m+2][j]);
state_data_q[4*i+m+2][j] = 1;//重要性標志置1
}
//第四位開始編碼
fprintf(context,"%d %d ",0,state_data_v[4*i+m+3][j]);
// state_data_pi[4*i+m+3][j] = 1;//標志此位被訪問過。
if(state_data_v[4*i+m+3][j])
{
//此時將符號位元編碼,有5種可能的情況(9-13)sign coding
// Encode sign bit
fprintf(context,"%d %d ",9,state_data_x[4*i+m+3][j]);
state_data_q[4*i+m+3][j] = 1;//重要性標志置1
}
break;
}
if(m == 1)
{
fprintf(context,"%d %d ",18,0);
fprintf(context,"%d %d ",18,1);
//此時將符號位元編碼,有5種可能的情況(9-13)sign coding
// Encode sign bit
fprintf(context,"%d %d ",9,state_data_x[4*i+m][j]);
state_data_q[4*i+m][j] = 1;//重要性標志置1
// state_data_pi[4*i+m-1][j] = 1;//標志此位被訪問過。
// state_data_pi[4*i+m][j] = 1;//標志此位被訪問過。
//第三位開始編碼
fprintf(context,"%d %d ",0,state_data_v[4*i+m+1][j]);
// state_data_pi[4*i+m+1][j] = 1;//標志此位被訪問過。
if(state_data_v[4*i+m+1][j])
{
//此時將符號位元編碼,有5種可能的情況(9-13)sign coding
// Encode sign bit
fprintf(context,"%d %d ",9,state_data_x[4*i+m+1][j]);
state_data_q[4*i+m+1][j] = 1;//重要性標志置1
}
//第四位開始編碼
fprintf(context,"%d %d ",0,state_data_v[4*i+m+2][j]);
// state_data_pi[4*i+m+2][j] = 1;//標志此位被訪問過。
if(state_data_v[4*i+m+2][j])
{
//此時將符號位元編碼,有5種可能的情況(9-13)sign coding
// Encode sign bit
fprintf(context,"%d %d ",9,state_data_x[4*i+m+2][j]);
state_data_q[4*i+m+2][j] = 1;//重要性標志置1
}
break;
}
if(m == 2)
{
fprintf(context,"%d %d ",18,1);
fprintf(context,"%d %d ",18,0);
//此時將符號位元編碼,有5種可能的情況(9-13)sign coding
// Encode sign bit
fprintf(context,"%d %d ",9,state_data_x[4*i+m][j]);
state_data_q[4*i+m][j] = 1;//重要性標志置1
// state_data_pi[4*i+m-2][j] = 1;//標志此位被訪問過。
// state_data_pi[4*i+m-1][j] = 1;//標志此位被訪問過。
// state_data_pi[4*i+m][j] = 1;//標志此位被訪問過。
fprintf(context,"%d %d ",0,state_data_v[4*i+m+1][j]);
// state_data_pi[4*i+m+1][j] = 1;//標志此位被訪問過。
if(state_data_v[4*i+m+1][j])
{
//此時將符號位元編碼,有5種可能的情況(9-13)sign coding
// Encode sign bit
fprintf(context,"%d %d ",9,state_data_x[4*i+m+1][j]);
state_data_q[4*i+m+1][j] = 1;//重要性標志置1
}
break;
}
if(m == 3)
{
fprintf(context,"%d %d ",18,1);
fprintf(context,"%d %d ",18,1);
//此時將符號位元編碼,有5種可能的情況(9-13)sign coding
// Encode sign bit
fprintf(context,"%d %d ",9,state_data_x[4*i+m][j]);
state_data_q[4*i+m][j] = 1;//重要性標志置1
// state_data_pi[4*i+m-3][j] = 1;//標志此位被訪問過。
// state_data_pi[4*i+m-2][j] = 1;//標志此位被訪問過。
// state_data_pi[4*i+m-1][j] = 1;//標志此位被訪問過。
// state_data_pi[4*i+m][j] = 1;//標志此位被訪問過。
break;
}
}
}
continue;
}
else
{
for(m=0;m<4;m++)
{
if(state_data_q[4*i+m][j]==0 && init_significant(f[4*i+m][j],0)==0)
{//當前系數不是重要性系數
fprintf(context,"%d %d ",init_significant(f[4*i+m][j],0),state_data_v[4*i+m][j]);
if(state_data_v[4*i+m][j])
{
state_data_q[4*i+m][j] = 1;
//unsigned char init_sign(unsigned int f, unsigned char v,int i,int j)
fprintf(context,"%d %d ",init_sign(f[4*i+m][j],state_data_x[4*i+m][j]),state_data_x[4*i+m][j]);
}
}
}
}
}
/******************************************************************************
//環境狀態字12位,顯示重要性狀態值。狀態變量如下所示:
// x;//符號變量
// q;//顯著性狀態變量
// e;//延遲顯著性狀態變量 表示系數是否是第一次被量值改進,也叫細化信息位
// v;//樣本比特值
// pi;//編碼狀態變量 表示位平面上的比特值是否已經被編碼,也叫訪問信息位
*******************************************************************************/
}
}
//到次為止完成三個通道的編碼。
}
fclose(context);
}
void encode_allsubband(int block_bufferin[BLOCKLENGTH][BLOCKWIDTH],
float interleave[LENGTH+8][WIDTH+8])
{
int i,j,m=0,n=0;
int image_size = LENGTH*WIDTH;
int block_size = BLOCKLENGTH*BLOCKWIDTH;
int blocksample[4][4] =
{
{1,6,-5,0},
{4,1,7,-4},
{0,5,-2,-5},
{-3,4,-3,1}
// {1,2,3,4},
// {1,2,3,4},
// {1,2,3,4},
// {1,2,3,4}
};
// long int c[16][8];
//for(k=8;)
// for(m=0;m<2;m++)
// for(n=0;n<2;n++)
{
printf("\nThe block_code sample is:");
for(i=0;i<BLOCKLENGTH;i++)
for(j=0;j<BLOCKWIDTH;j++)
{
//block_bufferin[i][j] = (floor)(interleave[i+4+m][j+4+n]+0.5);
block_bufferin[i][j] = blocksample[i][j];
if((!j%4))
printf("\n");
printf("%d ",block_bufferin[i][j]);
}
block_encode(block_bufferin);
}
}
/******************************************************************************
以上完成EBCOT的編碼,輸出送入MQ算術編碼器中
******************************************************************************/
void init_environment(unsigned int f[BLOCKLENGTH][BLOCKWIDTH],unsigned char
c[BLOCKLENGTH][BLOCKWIDTH],unsigned char state_data_x[BLOCKLENGTH][BLOCKWIDTH])
{
struct entironment_data
{
unsigned a12:1;
unsigned a11:1;
unsigned a10:1;
unsigned a9:1;
unsigned a8:1;
unsigned a7:1;
unsigned a6:1;
unsigned a5:1;
unsigned a4:1;
unsigned a3:1;
unsigned a2:1;
unsigned a1:1;
}state[BLOCKLENGTH][BLOCKWIDTH];
int i,j;
/******************************************************************************
//環境狀態變量 d0 v0 d1 a1 a5 a2 a9
h0 x h1 a7 x a8 a11 x a12
d2 v1 d3 a3 a6 a4 a10
******************************************************************************/
state[0][0].a12 = state_data_x[0][1] & 1;
state[0][0].a11 = 0;
state[0][0].a10 = state_data_x[1][0] & 1;
state[0][0].a9 = 0;
state[0][0].a8 = c[0][1] & 1;
state[0][0].a7 = 0;
state[0][0].a6 = c[1][0] & 1;
state[0][0].a5 = 0;
state[0][0].a4 = c[1][1] & 1;
state[0][0].a3 = 0;
state[0][0].a2 = 0;
state[0][0].a1 = 0;
state[0][BLOCKWIDTH-1].a12 = 0;
state[0][BLOCKWIDTH-1].a11 = state_data_x[0][BLOCKWIDTH-1-1] & 1;
state[0][BLOCKWIDTH-1].a10 = state_data_x[1][BLOCKWIDTH-1] & 1;
state[0][BLOCKWIDTH-1].a9 = 0;
state[0][BLOCKWIDTH-1].a8 = 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -