(信源三)词典压缩器的实现--LZO算法

    LZO 是致力于解压速度的一种数据压缩算法,LZO 是 Lempel-Ziv-Oberhumer 的缩写。这个算法是无损算法,参考实现程序是线程安全的。 实现它的一个自由软件工具是lzop。最初的库是用 ANSI C 编写、并且遵从 GNU通用公共许可证发布的。现在 LZO 有用于 Perl、Python 以及 Java 的各种版本。代码版权的所有者是 Markus F. X. J. Oberhumer

    LZO 库实现了许多有下述特点的算法:

    * 解压简单,速度非常快。
    * 解压不需要内存。
    * 压缩相当地快。
    * 压缩需要 64 kB 的内存。
    * 允许在压缩部分以损失压缩速度为代价提高压缩率,解压速度不会降低。
    * 包括生成预先压缩数据的压缩级别,这样可以得到相当有竞争力的压缩比。
    * 另外还有一个只需要 8 kB 内存的压缩级别。
    * 算法是线程安全的。
    * 算法是无损的。


第一步,实现代码基本调试: 
从网址https://www.oberhumer.com/opensource/lzo/下载miniLZO,解压后会看到其包含如下文件: 
(信源三)词典压缩器的实现--LZO算法_第1张图片


其中,lzoconf.h是LZO数据压缩库的配置,lzodefs.h是对体系结构、操作系统和编译器特定的定义,minilzo.h是迷你LZO实时数据压缩库的子集。minilzo.c是C语言版本的迷你LZO实时数据压缩库的子集,testmini.c是minilzo的测试文件。


(1)选择待压缩文件按钮

[cpp]  view plain  copy
  1. void CcompressDlg::OnBnClickedButton3()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     CString strFile = _T("");  
  5.   
  6.     CFileDialog    dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("Describe Files (*.cfg)|*.cfg|All Files (*.*)|*.*||"), NULL);  
  7.   
  8.     if (dlgFile.DoModal())  
  9.     {  
  10.         strFile = dlgFile.GetPathName();  
  11.     }  
  12.   
  13.     UpdateData(true);          // 获取数据  
  14.     path = strFile;  
  15.     UpdateData(false);         // 更新数据  
  16. }  
[cpp]  view plain   copy
  1. void CcompressDlg::OnBnClickedButton3()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     CString strFile = _T("");  
  5.   
  6.     CFileDialog    dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("Describe Files (*.cfg)|*.cfg|All Files (*.*)|*.*||"), NULL);  
  7.   
  8.     if (dlgFile.DoModal())  
  9.     {  
  10.         strFile = dlgFile.GetPathName();  
  11.     }  
  12.   
  13.     UpdateData(true);          // 获取数据  
  14.     path = strFile;  
  15.     UpdateData(false);         // 更新数据  
  16. }  


(2)选择解压缩文件按钮

[cpp]  view plain  copy
  1. void CcompressDlg::OnBnClickedButton4()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     CString strFile = _T("");  
  5.   
  6.     CFileDialog    dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("Describe Files (*.cfg)|*.cfg|All Files (*.*)|*.*||"), NULL);  
  7.   
  8.     if (dlgFile.DoModal())  
  9.     {  
  10.         strFile = dlgFile.GetPathName();  
  11.     }  
  12.   
  13.     UpdateData(true);          // 获取数据  
  14.     path_decompress = strFile;  
  15.     UpdateData(false);         // 更新数据  
  16. }  
[cpp]  view plain   copy
  1. void CcompressDlg::OnBnClickedButton4()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4.     CString strFile = _T("");  
  5.   
  6.     CFileDialog    dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("Describe Files (*.cfg)|*.cfg|All Files (*.*)|*.*||"), NULL);  
  7.   
  8.     if (dlgFile.DoModal())  
  9.     {  
  10.         strFile = dlgFile.GetPathName();  
  11.     }  
  12.   
  13.     UpdateData(true);          // 获取数据  
  14.     path_decompress = strFile;  
  15.     UpdateData(false);         // 更新数据  
  16. }  


(3)压缩按钮

[cpp]  view plain  copy
  1. void CcompressDlg::OnBnClickedButton1()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4. #ifdef _UNICODE  
  5.     LONG len1;  
  6.     len1 = WideCharToMultiByte(CP_ACP, 0, path, -1, NULL, 0, NULL, NULL);  
  7.     char *textPath = (char *)malloc(sizeof(char)*(len1 + 1));  
  8.     memset(textPath, 0, len1 + 1);  
  9.     WideCharToMultiByte(CP_ACP, 0, path, -1, textPath, len1 + 1, NULL, NULL);  
  10. #else  
  11.     ptr = new char[str.GetAllocLength() + 1];  
  12. #endif  
  13.     err = fopen_s(&ifp, textPath, "rb");  
  14.     if (err == 0)  
  15.     {  
  16.         printf("Thefile'crt_fopen_s.c'wasopened\n");  
  17.     }  
  18.     fseek(ifp, 0, SEEK_END);  
  19.     unsigned long len = ftell(ifp);  
  20.     myInLen = len;  
  21.     fseek(ifp, 0, SEEK_SET);  
  22.     cpTemp = (char*)malloc(len * sizeof(char));  
  23.     fread(cpTemp, sizeof(char), len, ifp);  
  24.     char *in = cpTemp;  
  25.     char *out = (char*)malloc((len + len / 16 + 64 + 3) * sizeof(char));  
  26.       
  27.     if (lzo_init() != LZO_E_OK)  
  28.     {  
  29.         printf("internal error - lzo_init() failed !!!\n");  
  30.         printf("(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable '-DLZO_DEBUG' for diagnostics)\n");  
  31.           
  32.     }  
  33.       
  34.     lzo_uint in_len;  
  35.     in_len = len;  
  36.     lzo_memset(in, 0, in_len);  
  37.     lzo_uint out_len;  
  38.   
  39.     int r;  
  40.       
  41.     r = lzo1x_1_compress((unsigned char*)in, in_len, (unsigned char*)out, &out_len, wrkmem);  
  42.     char mess[256];  
  43.   
  44.     if (r == LZO_E_OK)  
  45.     {  
  46.         sprintf_s(mess, sizeof(mess),  "压缩成功!\n\n原文件大小:%lu bytes\n压缩后大小:%lu bytes\n\n解压得到的文件“compress.txt”保存于工程目录下",  
  47.             (unsigned long)in_len, (unsigned long)out_len);  
  48.         MessageBox(CString(mess));  
  49.       
  50.     }  
  51.     else  
  52.     {  
  53.         /* this should NEVER happen */  
  54.         sprintf_s(mess, sizeof(mess), "压缩失败!\n %d\n", r);  
  55.         MessageBox(CString(mess));  
  56.     }  
  57.     /* check for an incompressible block */  
  58.     if (out_len >= in_len)  
  59.     {  
  60.         sprintf_s(mess, sizeof(mess), "未压缩!\n");  
  61.         MessageBox(CString(mess));  
  62.     }  
  63.   
  64.     err = fopen_s(&ofp, ".\\compress.txt""wb");  
  65.     fwrite(out, sizeof(char), out_len, ofp);  
  66.       
  67.     fclose(ifp);  
  68.     fclose(ofp);  
  69.     free(cpTemp);  
  70.     free(out);  
  71.     free(textPath);  
  72.   
  73. }  
[cpp]  view plain   copy
  1. void CcompressDlg::OnBnClickedButton1()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4. #ifdef _UNICODE  
  5.     LONG len1;  
  6.     len1 = WideCharToMultiByte(CP_ACP, 0, path, -1, NULL, 0, NULL, NULL);  
  7.     char *textPath = (char *)malloc(sizeof(char)*(len1 + 1));  
  8.     memset(textPath, 0, len1 + 1);  
  9.     WideCharToMultiByte(CP_ACP, 0, path, -1, textPath, len1 + 1, NULL, NULL);  
  10. #else  
  11.     ptr = new char[str.GetAllocLength() + 1];  
  12. #endif  
  13.     err = fopen_s(&ifp, textPath, "rb");  
  14.     if (err == 0)  
  15.     {  
  16.         printf("Thefile'crt_fopen_s.c'wasopened\n");  
  17.     }  
  18.     fseek(ifp, 0, SEEK_END);  
  19.     unsigned long len = ftell(ifp);  
  20.     myInLen = len;  
  21.     fseek(ifp, 0, SEEK_SET);  
  22.     cpTemp = (char*)malloc(len * sizeof(char));  
  23.     fread(cpTemp, sizeof(char), len, ifp);  
  24.     char *in = cpTemp;  
  25.     char *out = (char*)malloc((len + len / 16 + 64 + 3) * sizeof(char));  
  26.       
  27.     if (lzo_init() != LZO_E_OK)  
  28.     {  
  29.         printf("internal error - lzo_init() failed !!!\n");  
  30.         printf("(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable '-DLZO_DEBUG' for diagnostics)\n");  
  31.           
  32.     }  
  33.       
  34.     lzo_uint in_len;  
  35.     in_len = len;  
  36.     lzo_memset(in, 0, in_len);  
  37.     lzo_uint out_len;  
  38.   
  39.     int r;  
  40.       
  41.     r = lzo1x_1_compress((unsigned char*)in, in_len, (unsigned char*)out, &out_len, wrkmem);  
  42.     char mess[256];  
  43.   
  44.     if (r == LZO_E_OK)  
  45.     {  
  46.         sprintf_s(mess, sizeof(mess),  "压缩成功!\n\n原文件大小:%lu bytes\n压缩后大小:%lu bytes\n\n解压得到的文件“compress.txt”保存于工程目录下",  
  47.             (unsigned long)in_len, (unsigned long)out_len);  
  48.         MessageBox(CString(mess));  
  49.       
  50.     }  
  51.     else  
  52.     {  
  53.         /* this should NEVER happen */  
  54.         sprintf_s(mess, sizeof(mess), "压缩失败!\n %d\n", r);  
  55.         MessageBox(CString(mess));  
  56.     }  
  57.     /* check for an incompressible block */  
  58.     if (out_len >= in_len)  
  59.     {  
  60.         sprintf_s(mess, sizeof(mess), "未压缩!\n");  
  61.         MessageBox(CString(mess));  
  62.     }  
  63.   
  64.     err = fopen_s(&ofp, ".\\compress.txt""wb");  
  65.     fwrite(out, sizeof(char), out_len, ofp);  
  66.       
  67.     fclose(ifp);  
  68.     fclose(ofp);  
  69.     free(cpTemp);  
  70.     free(out);  
  71.     free(textPath);  
  72.   
  73. }  


(4)解压缩按钮

[cpp]  view plain  copy
  1. void CcompressDlg::OnBnClickedButton2()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4. #ifdef _UNICODE  
  5.     LONG len1;  
  6.     len1 = WideCharToMultiByte(CP_ACP, 0, path_decompress, -1, NULL, 0, NULL, NULL);  
  7.     char *textPath = (char *)malloc(sizeof(char)*(len1 + 1));  
  8.     memset(textPath, 0, len1 + 1);  
  9.     WideCharToMultiByte(CP_ACP, 0, path_decompress, -1, textPath, len1 + 1, NULL, NULL);  
  10. #else  
  11.     ptr = new char[str.GetAllocLength() + 1];  
  12. #endif  
  13.     err = fopen_s(&ifp, textPath, "rb");  
  14.     if (err == 0)  
  15.     {  
  16.         printf("Thefile'crt_fopen_s.c'was opened\n");  
  17.     }  
  18.     fseek(ifp, 0, SEEK_END);  
  19.     unsigned long len = ftell(ifp);  
  20.     fseek(ifp, 0, SEEK_SET);  
  21.     cpTemp = (char*)malloc(len * sizeof(char));  
  22.     fread(cpTemp, sizeof(char), len, ifp);  
  23.     char *in = cpTemp;  
  24.     char *out = (char *)malloc(len*100* sizeof(char));  
  25.     memset(out, 0, len * 100 * sizeof(char));  
  26.       
  27.     int r;  
  28.     lzo_uint new_len;  
  29.     r = lzo1x_decompress((unsigned char*)in, len, (unsigned char*)out, &new_len, NULL);  
  30.   
  31.     char mess[256];  
  32.     if (r == LZO_E_OK && new_len == myInLen)  
  33.     {  
  34.         sprintf_s(mess, sizeof(mess), "解压成功!\n\n待解压文件大小: %lu bytes\n解压后文件大小: %lu bytes\n\n解压得到的文件“decompress.txt”保存于工程目录下",  
  35.             (unsigned long)len, (unsigned long)new_len);  
  36.         MessageBox(CString(mess));  
  37.     }  
  38.     else  
  39.     {  
  40.         /* this should NEVER happen */  
  41.         sprintf_s(mess, sizeof(mess), "解压失败! %d\n", r);  
  42.         MessageBox(CString(mess));  
  43.     }  
  44.     err = fopen_s(&ofp, ".\\decompress.txt""wt+");  
  45.     fwrite(out, sizeof(char), new_len, ofp);  
  46.   
  47.     fclose(ifp);  
  48.     fclose(ofp);  
  49.     free(cpTemp);  
  50.     free(textPath);  
  51.     free(out);  
  52. }  
[cpp]  view plain   copy
  1. void CcompressDlg::OnBnClickedButton2()  
  2. {  
  3.     // TODO: 在此添加控件通知处理程序代码  
  4. #ifdef _UNICODE  
  5.     LONG len1;  
  6.     len1 = WideCharToMultiByte(CP_ACP, 0, path_decompress, -1, NULL, 0, NULL, NULL);  
  7.     char *textPath = (char *)malloc(sizeof(char)*(len1 + 1));  
  8.     memset(textPath, 0, len1 + 1);  
  9.     WideCharToMultiByte(CP_ACP, 0, path_decompress, -1, textPath, len1 + 1, NULL, NULL);  
  10. #else  
  11.     ptr = new char[str.GetAllocLength() + 1];  
  12. #endif  
  13.     err = fopen_s(&ifp, textPath, "rb");  
  14.     if (err == 0)  
  15.     {  
  16.         printf("Thefile'crt_fopen_s.c'was opened\n");  
  17.     }  
  18.     fseek(ifp, 0, SEEK_END);  
  19.     unsigned long len = ftell(ifp);  
  20.     fseek(ifp, 0, SEEK_SET);  
  21.     cpTemp = (char*)malloc(len * sizeof(char));  
  22.     fread(cpTemp, sizeof(char), len, ifp);  
  23.     char *in = cpTemp;  
  24.     char *out = (char *)malloc(len*100* sizeof(char));  
  25.     memset(out, 0, len * 100 * sizeof(char));  
  26.       
  27.     int r;  
  28.     lzo_uint new_len;  
  29.     r = lzo1x_decompress((unsigned char*)in, len, (unsigned char*)out, &new_len, NULL);  
  30.   
  31.     char mess[256];  
  32.     if (r == LZO_E_OK && new_len == myInLen)  
  33.     {  
  34.         sprintf_s(mess, sizeof(mess), "解压成功!\n\n待解压文件大小: %lu bytes\n解压后文件大小: %lu bytes\n\n解压得到的文件“decompress.txt”保存于工程目录下",  
  35.             (unsigned long)len, (unsigned long)new_len);  
  36.         MessageBox(CString(mess));  
  37.     }  
  38.     else  
  39.     {  
  40.         /* this should NEVER happen */  
  41.         sprintf_s(mess, sizeof(mess), "解压失败! %d\n", r);  
  42.         MessageBox(CString(mess));  
  43.     }  
  44.     err = fopen_s(&ofp, ".\\decompress.txt""wt+");  
  45.     fwrite(out, sizeof(char), new_len, ofp);  
  46.   
  47.     fclose(ifp);  
  48.     fclose(ofp);  
  49.     free(cpTemp);  
  50.     free(textPath);  
  51.     free(out);  
  52. }  

界面效果如图所示:

(信源三)词典压缩器的实现--LZO算法_第2张图片


之后选择压缩文件路径进行压缩即可得到压缩和解压目的


你可能感兴趣的:(通信,信源编码,算法,压缩)