⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modified_ebcot.c

📁 这是我刚刚完成的关于JPEG2000的C语言实现的部分程序。小波变换是采用97变换
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
功能描述:
   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
		{					
		//开始重要性传播位平面的重要性扫描通道,处理当前不显著,但具有显著邻域的样本
			if(state_data_q[4*i][j]==0 && init_significant(f[4*i][j],0)>0 &&init_significant(f[4*i][j],0)<9)
			{//当前系数不是重要性系数,上下文区域不是0							
				fprintf(context,"%d %d ",init_significant(f[4*i][j],0),state_data_v[4*i][j]);
				if(state_data_v[4*i][j])
				{
					state_data_q[4*i][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][j],state_data_x[4*i][j]),state_data_x[4*i][j]);				
				}
				state_data_pi[4*i][j] = 1;
			for(m=1;m<4;m++)	
			{//开始重要性传播位平面的重要性扫描通道,处理当前不显著,但具有显著邻域的样本
				if(state_data_q[4*i+m][j]==0 && init_significant(f[4*i+m][j],0)>0 &&init_significant(f[4*i+m][j],0)<9)
				{//当前系数不是重要性系数,上下文区域不是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;		
				}
				//开始清除通过,此扫描数据没有经过前两个通道则进入清除通道编码
				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]);				
					}					
				}			
			}
			continue;		
			}
			else
				state_data_pi[4*i][j] = 0;
		//开始幅值细化通过,位平面的幅度细化扫描通道
			if(state_data_q[4*i][j]==1 && state_data_pi[4*i][j]==0)  
			{//该系数是重要的,						
				fprintf(context,"%d %d ",init_magnitude(f[4*i][j],state_data_e[4*i][j]),state_data_v[4*i][j]);
				state_data_e[4*i][j] = 1;
			for(m=1;m<4;m++)	
			{//开始重要性传播位平面的重要性扫描通道,处理当前不显著,但具有显著邻域的样本
				if(state_data_q[4*i+m][j]==0 && init_significant(f[4*i+m][j],0)>0 &&init_significant(f[4*i+m][j],0)<9)
				{//当前系数不是重要性系数,上下文区域不是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;		
				}
				//开始清除通过,此扫描数据没有经过前两个通道则进入清除通道编码
				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]);				
					}					
				}			
			}
			continue;
			}
		
//开始清除通过
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 ",init_sign(f[4*i+m][j],state_data_x[4*i+m][j]),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 ",init_significant(f[4*i+m+1][j],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 ",init_sign(f[4*i+m+1][j],state_data_x[4*i+m+1][j]),state_data_x[4*i+m+1][j]);
							state_data_q[4*i+m+1][j] = 1;//重要性标志置1
						}
						//第三位开始编码
						fprintf(context,"%d %d ",init_significant(f[4*i+m+2][j],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 ",init_sign(f[4*i+m+2][j],state_data_x[4*i+m+2][j]),state_data_x[4*i+m+2][j]);
							state_data_q[4*i+m+2][j] = 1;//重要性标志置1
						}
						//第四位开始编码
						fprintf(context,"%d %d ",init_significant(f[4*i+m+3][j],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 ",init_sign(f[4*i+m+3][j],state_data_x[4*i+m+3][j]),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 ",init_sign(f[4*i+m][j],state_data_x[4*i+m][j]),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 ",init_significant(f[4*i+m+1][j],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 ",init_sign(f[4*i+m+1][j],state_data_x[4*i+m+1][j]),state_data_x[4*i+m+1][j]);
							state_data_q[4*i+m+1][j] = 1;//重要性标志置1
						}
						//第四位开始编码
						fprintf(context,"%d %d ",init_significant(f[4*i+m+2][j],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 ",init_sign(f[4*i+m+2][j],state_data_x[4*i+m+2][j]),state_data_x[4*i+m+2][j]);
							state_data_q[4*i+m+2][j] = 1;//重要性标志置1

						}
						break;
						}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -