寻求二进制整型数文件的无损数据压缩方法

jiaanxue 2009-10-12 05:35:00
寻求二进制整型数文件的无损数据压缩方法
各位高手请指点二进制整型数文件的压缩方法,无损压缩算法,本人已经尝试了LZW算法、LZW154V算法和算术编码,LZW算法、LZW154V算法对文件无压缩效果,算数编码压缩后占用空间为原来的90%,有没有更好的无损压缩方法,能达到50%才好,请高手指点。
...全文
566 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
jiaanxue 2010-08-05
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 forestdb 的回复:]
帮顶。
[/Quote]
谢谢
ForestDB 2010-07-10
  • 打赏
  • 举报
回复
帮顶。
godcomme 2010-07-09
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 uestcshaw 的回复:]

二进制整型数文件??你要是存放的是二进制文件,lzw对二进制文件的压缩效果不会总是90%那么差吧,有时的压缩效果应该还是可以的!!!
[/Quote]

这位兄弟,貌似你也是研究音频压缩算法的?
可否留个联系方式一起交流交流!
jiaanxue 2009-12-08
  • 打赏
  • 举报
回复
发现了一个错误,修改后wav文件头添加成功,如下:
c++程序
//===================以下文件用于生成wav格式的文件2009-11-23==================================================
struct RIFF_HEADER//文件类型
{
char szRiffID[4]; // 'R','I','F','F'
DWORD dwRiffSize; //DWORD最大可容纳4GB的文件大小=FILE_LENGTH-8(该size是整个wav文件大小减去ID和Size所占用的字节数,即FileLen - 8 = Size)
char szRiffFormat[4]; // 'W','A','V','E'
};
struct WAVE_FORMAT
{
WORD wFormatTag; //2 Bytes,编码方式一般为0x0001
WORD wChannels; //2 Bytes,声道数目,1--单声道,2--双声道
DWORD dwSamplesPerSec; //4 Bytes采样频率
DWORD dwAvgBytesPerSec; //4 Bytes每秒所需字节数
WORD wBlockAlign; //2 Bytes数据块对齐单位(每个采样需要的字节数)
WORD wBitsPerSample; //2 Bytes每个采样需要的bit数
};
struct FMT_BLOCK//格式
{
char szFmtID[4]; // 'f','m','t',' '
DWORD dwFmtSize; //一般情况下为16,如有附加信息为18
WAVE_FORMAT wavFormat;
};
struct FACT_BLOCK//可先项 一般可不用
{
char szFactID[4]; //4 Bytes'f','a','c','t'
DWORD dwFactSize; //4 Bytes数值为4
};
struct DATA_BLOCK//数据头
{
char szDataID[4];// 'd','a','t','a'
DWORD dwDataSize;//4 Bytes 声音数据的数据长度,字节,用这个数据大小除以nAvgBytesPerSec既得文件的播放时间
};


void CMainFrame::OnCreateWav()
{
// TODO: Add your command handler code here
fstream input_1;
fstream output_1;
CString input_1_path;
CString output_1_path;
short data_1;
short data_2;
short m_3=255;//m_3的二进制位00000000 11111111
long datasize;
CString s;
RIFF_HEADER riff;
WAVE_FORMAT wform;
FMT_BLOCK fmt;
FACT_BLOCK fact;
DATA_BLOCK data;

fmt.wavFormat.wFormatTag=1;//0x0001;//1,0x0001即
fmt.wavFormat.wChannels=1*1; //0x0001 即单声道
fmt.wavFormat.dwSamplesPerSec=11025;// //0x00001F40 即采样率8000Hz
fmt.wavFormat.dwAvgBytesPerSec=11025*2;// //0x00003E80 即平均字节速率16000字节(16bit量化),可以根据该数据估计缓冲区的大小;
fmt.wavFormat.wBlockAlign=1*2; //0x0002 即块联合为2字节(16bit量化,2字节表示一个采样点,播放时必须从以块为单位从块头开始播放)
fmt.wavFormat.wBitsPerSample=8*2;// //0x0010 即每个采样点的比特值为16(16bit量化)。nBlockAlign值即由该值除以8计算出来;
sprintf(fmt.szFmtID,"%s","fmt ");
fmt.dwFmtSize=16;//一般情况下为16,如有附加信息为18

//===================数据文件打开及获取文件大小=========================================================================
//选取要取绝对值的的二进制波形的数据文件///////////////////////////
AfxMessageBox("选择二进制波形数据文件!");
CFileDialog dlg_input_1(TRUE,_T("dat"),NULL,
OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,
_T("Text File(*.dat)|*.dat|ALL Files(*.*)|*.*||"));
if(dlg_input_1.DoModal()!=IDOK)
{
AfxMessageBox("二进制波形数据文件打开错误!");
return;
}
input_1_path=dlg_input_1.GetPathName();
input_1.open(input_1_path,ios::in|ios::nocreate|ios::binary);
if(input_1.fail())
{
AfxMessageBox("can not open file:");
return;
}
//选取存放绝对值的二进制文件保存路径///////////////////////
AfxMessageBox("选取wav格式二进制文件保存路径!");
CFileDialog dlg_output_1(FALSE,_T("dat"),NULL,
OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,
_T("Text File(*.dat)|*.dat|ALL Files(*.*)|*.*||"),NULL);
if(dlg_output_1.DoModal()!=IDOK)
{
AfxMessageBox("波形数据文件打开错误!");
return;
}
output_1_path=dlg_output_1.GetPathName();
output_1.open(output_1_path,ios::out|ios::app|ios::binary);
if(!output_1)
{
AfxMessageBox("can not open file:");
return;
}
//获取文件大小//////////////////////////////////////////////
input_1.seekg(0,ios::beg); //定位到文件开头
streampos begin=input_1.tellg(); //获得开头的位置
input_1.seekg(0,ios::end); //定位到文件尾部
streampos end=input_1.tellg(); //获得尾部的位置
datasize=(long)(end-begin); //利用streampos的"-"操作得到文件的字节长度
input_1.seekg(0,ios::beg); //定位到文件开头
//========================================================================================================
sprintf(data.szDataID,"%s","data");
data.dwDataSize=datasize;//用这个数据大小除以nAvgBytesPerSec既得文件的播放时间

riff.dwRiffSize=datasize+sizeof(FMT_BLOCK)+sizeof(DATA_BLOCK)+sizeof(RIFF_HEADER)-8;
strncpy(riff.szRiffFormat,"WAVE",4);
sprintf(riff.szRiffID,"%s","RIFF");

output_1.write((char*)&riff,sizeof(RIFF_HEADER));//写RIFF_HEADER
output_1.write((char*)&fmt,sizeof(FMT_BLOCK));//写FMT_BLOCK
output_1.write((char*)&data,sizeof(DATA_BLOCK));//写数据头 DATA_BLOCK
while(!(input_1.eof()))
{//遇到文件结束或读取操作失败时结束读操作
input_1.read((char *)&data_1,2);
if(input_1.eof())
{
break;
}
data_2=data_1;
data_1=data_1 < <8;//低8位移至高8位保留,低8位变为00000000
data_2=data_2>>8;//高8位移至低8位保留
data_2=data_2&m_3;////把高八位清0,保留低八位,m_3的二进制位00000000 11111111
data_1=data_1|data_2;
output_1.write((char*)&data_1,2);
}

input_1.close();
output_1.close();

AfxMessageBox("over!\nover!");
}
jiaanxue 2009-12-08
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 uestcshaw 的回复:]
二进制整型数文件??你要是存放的是二进制文件,lzw对二进制文件的压缩效果不会总是90%那么差吧,有时的压缩效果应该还是可以的!!!
[/Quote]
我试过,好像目前只有算数编码还可以,但是效果不好,现在尝试音频压缩算法,但是在转化为wav格式文件时出了问题
请大家指教:
c++程序
//===================以下文件用于生成wav格式的文件2009-11-23==================================================
struct RIFF_HEADER//文件类型
{
char szRiffID[4]; // 'R','I','F','F'
DWORD dwRiffSize; //DWORD最大可容纳4GB的文件大小=FILE_LENGTH-8(该size是整个wav文件大小减去ID和Size所占用的字节数,即FileLen - 8 = Size)
char szRiffFormat[4]; // 'W','A','V','E'
};
struct WAVE_FORMAT
{
WORD wFormatTag; //2 Bytes,编码方式一般为0x0001
WORD wChannels; //2 Bytes,声道数目,1--单声道,2--双声道
DWORD dwSamplesPerSec; //4 Bytes采样频率
DWORD dwAvgBytesPerSec; //4 Bytes每秒所需字节数
WORD wBlockAlign; //2 Bytes数据块对齐单位(每个采样需要的字节数)
WORD wBitsPerSample; //2 Bytes每个采样需要的bit数
};
struct FMT_BLOCK//格式
{
char szFmtID[4]; // 'f','m','t',' '
DWORD dwFmtSize; //一般情况下为16,如有附加信息为18
WAVE_FORMAT wavFormat;
};
struct FACT_BLOCK//可先项 一般可不用
{
char szFactID[4]; //4 Bytes'f','a','c','t'
DWORD dwFactSize; //4 Bytes数值为4
};
struct DATA_BLOCK//数据头
{
char szDataID[4];// 'd','a','t','a'
DWORD dwDataSize;//4 Bytes 声音数据的数据长度,字节,用这个数据大小除以nAvgBytesPerSec既得文件的播放时间
};


void CMainFrame::OnCreateWav()
{
// TODO: Add your command handler code here
fstream input_1;
fstream output_1;
CString input_1_path;
CString output_1_path;
short data_1;
short data_2;
short m_3=255;//m_3的二进制位00000000 11111111
long datasize;
CString s;
RIFF_HEADER riff;
WAVE_FORMAT wform;
FMT_BLOCK fmt;
FACT_BLOCK fact;
DATA_BLOCK data;

fmt.wavFormat.wFormatTag=1;//0x0001;//1,0x0001即
fmt.wavFormat.wChannels=1*1; //0x0001 即单声道
fmt.wavFormat.dwSamplesPerSec=11025;// //0x00001F40 即采样率8000Hz
fmt.wavFormat.dwAvgBytesPerSec=11025*2;// //0x00003E80 即平均字节速率16000字节(16bit量化),可以根据该数据估计缓冲区的大小;
fmt.wavFormat.wBlockAlign=1*2; //0x0002 即块联合为2字节(16bit量化,2字节表示一个采样点,播放时必须从以块为单位从块头开始播放)
fmt.wavFormat.wBitsPerSample=8*2;// //0x0010 即每个采样点的比特值为16(16bit量化)。nBlockAlign值即由该值除以8计算出来;
sprintf(fmt.szFmtID,"%s","fmt ");
fmt.dwFmtSize=16;//一般情况下为16,如有附加信息为18

//===================数据文件打开及获取文件大小=========================================================================
//选取要取绝对值的的二进制波形的数据文件///////////////////////////
AfxMessageBox("选择二进制波形数据文件!");
CFileDialog dlg_input_1(TRUE,_T("dat"),NULL,
OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,
_T("Text File(*.dat)|*.dat|ALL Files(*.*)|*.*||"));
if(dlg_input_1.DoModal()!=IDOK)
{
AfxMessageBox("二进制波形数据文件打开错误!");
return;
}
input_1_path=dlg_input_1.GetPathName();
input_1.open(input_1_path,ios::in|ios::nocreate|ios::binary);
if(input_1.fail())
{
AfxMessageBox("can not open file:");
return;
}
//选取存放绝对值的二进制文件保存路径///////////////////////
AfxMessageBox("选取wav格式二进制文件保存路径!");
CFileDialog dlg_output_1(FALSE,_T("dat"),NULL,
OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,
_T("Text File(*.dat)|*.dat|ALL Files(*.*)|*.*||"),NULL);
if(dlg_output_1.DoModal()!=IDOK)
{
AfxMessageBox("波形数据文件打开错误!");
return;
}
output_1_path=dlg_output_1.GetPathName();
output_1.open(output_1_path,ios::out|ios::app|ios::binary);
if(!output_1)
{
AfxMessageBox("can not open file:");
return;
}
//获取文件大小//////////////////////////////////////////////
input_1.seekg(0,ios::beg); //定位到文件开头
streampos begin=input_1.tellg(); //获得开头的位置
input_1.seekg(0,ios::end); //定位到文件尾部
streampos end=input_1.tellg(); //获得尾部的位置
datasize=(long)((end-begin)/2); //利用streampos的"-"操作得到文件的字节长度
input_1.seekg(0,ios::beg); //定位到文件开头
//========================================================================================================
sprintf(data.szDataID,"%s","data");
data.dwDataSize=datasize;//用这个数据大小除以nAvgBytesPerSec既得文件的播放时间

riff.dwRiffSize=datasize+sizeof(FMT_BLOCK)+sizeof(DATA_BLOCK)+sizeof(RIFF_HEADER)-8;
strncpy(riff.szRiffFormat,"WAVE",4);
sprintf(riff.szRiffID,"%s","RIFF");

output_1.write((char*)&riff,sizeof(RIFF_HEADER));//写RIFF_HEADER
output_1.write((char*)&fmt,sizeof(FMT_BLOCK));//写FMT_BLOCK
output_1.write((char*)&data,sizeof(DATA_BLOCK));//写数据头 DATA_BLOCK
while(!(input_1.eof()))
{//遇到文件结束或读取操作失败时结束读操作
input_1.read((char *)&data_1,2);
if(input_1.eof())
{
break;
}
data_2=data_1;
data_1=data_1<<8;//低8位移至高8位保留,低8位变为00000000
data_2=data_2>>8;//高8位移至低8位保留
data_2=data_2&m_3;////把高八位清0,保留低八位,m_3的二进制位00000000 11111111
data_1=data_1|data_2;
output_1.write((char*)&data_1,2);
}

input_1.close();
output_1.close();

AfxMessageBox("over!\nover!");
}
uestcshaw 2009-10-21
  • 打赏
  • 举报
回复
二进制整型数文件??你要是存放的是二进制文件,lzw对二进制文件的压缩效果不会总是90%那么差吧,有时的压缩效果应该还是可以的!!!
uestcshaw 2009-10-21
  • 打赏
  • 举报
回复
你可以试试开源的lzma算法,有开源的代码,下载一个lzma SDK,然后裁剪就可以用了。。。。。
java_bird_09 2009-10-12
  • 打赏
  • 举报
回复
只能观摩学习了。。。
jackyjkchen 2009-10-12
  • 打赏
  • 举报
回复
如果lz系列算法都压缩不了……那就没有更好的了,一般的文件lzma极限压缩能压倒30%以下
sea_spray 2009-10-12
  • 打赏
  • 举报
回复
学习
  • 打赏
  • 举报
回复
并不是所有数据都能压缩的。
比如jpeg就压缩不了什么

33,321

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧