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

📄 arithmap.cpp

📁 一个我自己整理打包好的自适应二进制算术编码程序
💻 CPP
字号:
//arithmap.cpp
#include "airthmap.h"
#include "ac.h"
#include "base.h"
#define ADAPT 1
arithmap::arithmap()
{
	sourcedata = NULL;
	changedata = NULL;
	mapmodel = NULL;
	map_num = 0;
	data_size = 0;
}
arithmap::~arithmap()
{
	check_pointer(changedata);
	check_pointer(sourcedata);
	check_pointer(mapmodel);
}
//映射函数,根据符号求对应的坐标值
inline int arithmap::Mapping(int value)
{
	//为了提高速度,可以采用二分法,这里先用最原始的方法,待改进
	int i=0;
	for (i=0;i<map_num;i++)
	{
		if(mapmodel[i]==value)
			return i;
		else continue;
	}
	return -1;//其实这个没用,不会走这一步的
}
void arithmap::GetSourceData(bool type)
{
	FILE *fpsource = NULL;
	fpsource = fopen(str_in_file,"r");
	checkfile(fpsource,str_in_file);
	int i = 0;
	check_pointer(sourcedata);
	sourcedata = new int[data_size];
	memset(sourcedata,0,sizeof(int)*data_size);
	for(i=0;i<data_size;i++)
	{
		if (type == TRUE)
			fscanf(fpsource,"%d",&sourcedata[i]);//文本文件
		else
			fread(&sourcedata[i],sizeof(int),1,fpsource);//二进制文件
	}
	fclose(fpsource);
	fpsource = NULL;
}
void arithmap::GetMappingArray()
{
	//从sourcedata中获得映射数组,以便将sourcedata转化为自然数的形式
	//先得到最大最小值
	int i = 0;
	int minnum=0,maxnum=0;
	for(i=0;i<data_size;i++)
	{
		if (sourcedata[i]<minnum)
		{
			minnum = sourcedata[i];
		}
		if (sourcedata[i]>maxnum)
		{
			maxnum = sourcedata[i];
		}
	}
	int length=0;
	length=maxnum - minnum + 1;
	//建立一个大小为length=maxnum-minnum+1的数组,确定出现次数不为零的符号
	int *prenum=new int[length];
	memset(prenum , 0 ,sizeof(int)*length);
	//然后开始循环
	for (i=0;i<data_size;i++)
	{
		prenum[sourcedata[i]-minnum]++;
	}
	//开始统计出现过的符号
	for (i=0;i<length;i++)
	{
		if (prenum[i]!=0)
		{
			map_num++;
		}
	}
	//得到映射数组
	mapmodel=new int [map_num];
	int j=0;
	for (i=0;i<length;i++)
	{
		if (prenum[i]!=0)
		{
			mapmodel[j]=i+minnum;
			j++;
		}
	}
	delete[] prenum;
	prenum = NULL;
}
void arithmap::AirthEncode()
{
	//No.1 打开文件 获取数据
	GetSourceData();
	//No.2 获得映射数组
 	GetMappingArray();
	//No.3 根据映射关系替换原始数据
 	ChangeSourceData();
	//删除原始数据
	check_pointer(sourcedata);
	//对映射结果进行编码
	str_result_encode_file = "map_result_encode.txt";
	ArithEncodeChangeResult();
	//现在开始写入具体编码结果1 数组大小  映射关系 2 编码大小 编码数据
	//打开编码文件
	FILE *fp_encode = NULL;
	fp_encode = fopen(str_out_file,"wb");
	checkfile(fp_encode,str_out_file);
	//写入映射数组大小和映射关系
	fwrite(&map_num,sizeof(int),1,fp_encode);
	for (int i=0;i<map_num;i++)
	{
		fwrite(&mapmodel[i],sizeof(int),1,fp_encode);
	}
	//然后写入预测结果
	FILE *fpsource = NULL;
	fpsource=fopen(str_result_encode_file,"rb");
	checkfile(fpsource,str_result_encode_file);
	int count=0;
	char ch;
	//得到编码长度
	while(!feof(fpsource))
	{
		ch=fgetc(fpsource);
		count++;
	}
	count-=1;
	//写入编码长度
	fwrite(&count,sizeof(int),1,fp_encode);
	//写入编码结果
	rewind(fpsource);
	for (i=0;i<count;i++)
	{
		ch=fgetc(fpsource);
		fputc(ch,fp_encode);
	}
	fclose(fp_encode);
	fp_encode = NULL;
	check_pointer(changedata);
	check_pointer(mapmodel);
}
//该函数的作用是将不连续的预测树据用连续的相对应的自然数替换
void arithmap::ChangeSourceData()
{
	int i=0;
	changedata = new int[data_size];
	memset(changedata,0,sizeof(int)*data_size);
	for (i=0;i<data_size;i++)
	{
		changedata[i]=Mapping(sourcedata[i]);
	}
}
void arithmap::ArithEncodeChangeResult()
{
	ac_encoder ace;
	ac_model acm;
	CString outname = str_result_encode_file;
	ac_encoder_init(&ace, outname);
	ac_model_init(&acm, map_num, NULL, ADAPT);
	int count=data_size;
	int i;
	for (i=0;i<count;i++)
	{
		ac_encode_symbol(&ace, &acm, changedata[i]);
	}	
	ac_encoder_done(&ace);
	ac_model_done(&acm);
}
void arithmap::SerparateData()
{
	FILE *fp_serp_source = NULL;
	fp_serp_source = fopen(str_in_file,"rb");
	checkfile(fp_serp_source,str_in_file);
	FILE *fp = NULL;
	fp = fopen(str_result_encode_file,"wb");
	checkfile(fp,str_result_encode_file);
	fread(&map_num,sizeof(int),1,fp_serp_source);
	check_pointer(mapmodel);
	mapmodel = new int[map_num];
	memset(mapmodel,0,sizeof(int)*map_num);
	for (int i=0;i<map_num;i++)
	{
		fread(&mapmodel[i],sizeof(int),1,fp_serp_source);
	}

	int count = 0;
	fread(&count , sizeof(int) ,1, fp_serp_source);
	char ch;
	for (i = 0;i<count;i++)
	{
		ch=fgetc(fp_serp_source);
		fputc(ch,fp);
	}
	fclose(fp);
	fclose(fp_serp_source);
	fp = NULL;
	fp_serp_source = NULL;
}
void arithmap::AirthDecode()
{
	//先得到数据编码结果
	str_result_encode_file = "map_result_encode.txt";
	SerparateData();
	//先解压为自然数表示的形式
	int i;
	FILE *fp;
	int c;
	ac_decoder acd;
	ac_model acm;
	CString inname = str_in_file;
	char *outname="decode_middle.txt";
	acd.fp = fopen (str_result_encode_file, "rb");
	fp = fopen(outname, "wb");
	checkfile(acd.fp,str_result_encode_file);
	checkfile(fp,outname);
	ac_decoder_init(&acd);
	ac_model_init(&acm, map_num, NULL, ADAPT);
	int count =data_size;
	for (i=0;i<count;i++)
	{
		c = ac_decode_symbol(&acd, &acm);
		fwrite(&c,sizeof(int),1,fp);
	}
	ac_decoder_done(&acd);
	ac_model_done(&acm);
	fclose(fp);
	//恢复原来结果
	FILE *fp1=fopen("decode_middle.txt","rb");
	FILE *fp2=fopen(str_out_file,"w");
	checkfile(fp1,"decode_middle.txt");
	checkfile(fp2,str_out_file);
	int value=0;
	int j=0;
	for (i=0;i<data_size;i++)
	{
		fread(&value,sizeof(int),1,fp1);
		fprintf(fp2,"%d ",mapmodel[value]);
	}
	fclose(fp1);
	fclose(fp2);
}

⌨️ 快捷键说明

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