📄 arithmap.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 + -