
visual_studio_ZLIB
Visual Studio-ZLIB壓縮同解壓
『ZLIB』開源『壓縮』同『解壓』程式庫, 支持『DEFLATE』冇損壓縮演算法,佢混合『LZ77演算法』同『霍夫曼編碼』.
『DEFLATE』壓縮演算法冇專利權.畀人大量應用係『網絡』『圖檔』『文檔』『影片』.
| .PNG/ Libpng | 圖檔解壓 |
| .ZIP | 壓縮檔 |
| .tar | 壓縮檔 |
| .gz | 壓縮檔 |
| HTTP | 壓縮傅送 |
| FFmpeg | 影片解壓 |
下載『ZLIB』
| http://www.zlib.net/ |
| http://www.zlib.net/zlib-1.2.13.tar.gz |
『Android studio』內置『ZLIB』, 唔使下載.但要係『CMakeLists.txt』增添『zlib』庫.
| CMakeLists.txt文檔 | |
| find_library( z-lib z ) | 搜索zlib |
| target_link_libraries( ${z-lib} ) | 連接zlib |
包含『ZLIB』頭文檔
| #include <zlib.h> | Zlib-api |
| #include <zconf.h> |
『z_stream』壓縮同解壓皆需此結構體
| z_stream stream; | zlib流結構體 |
| stream.zalloc = Z_NULL; | NULL用默認記憶體分配函數 |
| stream.zfree = Z_NULL; | NULL用默認記憶體釋放函數 |
| stream.opaque = Z_NULL; | |
| stream.next_in = (Bytef*)sour; | 蒞源 |
| stream.avail_in = (uInt)sour_length; | 蒞源長 |
| stream.next_out = dest; | 輸出 |
| stream.avail_out = (uInt)*dest_length; | 輸出長 |
『ZLIB』壓縮分三步
| 壓縮 | |
| deflateInit(&stream, level) | 分配記憶體,level壓縮等級 |
| deflate(&stream, flush); | 壓縮數據, flush設0 |
| deflateEnd(&stream); | 釋放記憶體 |
| int deflateInit2( | deflateInit()加強版 |
| z_streamp strm, | zlib流結構體 |
| int level, | level壓縮等級0~9.
0:速度快,唔壓縮. 9:速度慢,壓縮率高. |
| int method, | 壓縮演算法僅支緩Z_DEFLATED |
| int windowBits, | 處理RAW DEFLATE手法. |
| int memLevel, | 指定記憶體分配MAX_MEM_LEVEL |
| int strategy)); | 壓縮策略,僅影響壓縮比.默認Z_DEFAULT_STRATEGY |
| level | 壓縮等級 |
| #define Z_NO_COMPRESSION 0 | 唔壓縮 |
| #define Z_BEST_SPEED 1 | 高速,低壓縮率 |
| #define Z_BEST_COMPRESSION 9 | 高壓縮率, 慢速 |
| #define Z_DEFAULT_COMPRESSION (-1) | 默認壓縮 |
| windowBits | 處理RAW DEFLATE手法. |
| 8~15: | 純deflate壓縮 |
| -8~-15: | zlib頭 + deflate + zlib尾 |
| > 16: | Gzip頭+ deflate + Gzip尾 |
| method | 壓縮演算法 |
| #define Z_DEFLATED 8 | DEFLATE冇損壓縮 |
| memLevel | 記憶體分配 |
| MemLevel=1 | 最小記憶體,速度慢壓縮比低 |
| MemLevel=9
#define MAX_MEM_LEVEL 9 |
最大記憶體,最佳速度 |
| MemLevel=8 | 默認值 |
| strategy | 壓縮演算法設定 |
| #define Z_FILTERED 1 | 僅FILTERED生成數據 |
| #define Z_HUFFMAN_ONLY 2 | 僅霍夫曼編碼 |
| #define Z_RLE 3 | 匹配長度=1 |
| #define Z_FIXED 4 | 禁霍夫曼編碼 |
| #define Z_DEFAULT_STRATEGY 0 | 默認壓縮設定 |
| int deflate(z_stream *strm, int flush); | 壓縮/解壓 |
| strm: | z_stream 結構 |
| flush: | 操作標誌 |
| 返回值 |
| flush | 操作標誌 |
| Z_NO_FLUSH: | 標准壓縮操作 |
| Z_SYNC_FLUSH: | 同步刷新操作 |
| Z_FULL_FLUSH: | 完全刷新操作 |
| Z_FINISH: | 結束操作, 壓縮完成後返回 |
| deflate()返回值 | |
| Z_OK: | 壓縮操作成功 |
| Z_STREAM_END: | 輸入資料釋數壓縮, 壓縮器處於結束狀態 |
| Z_BUF_ERROR: | 緩衝吾够 |
| Z_STREAM_ERROR: | 內部錯誤 |
『ZLIB』解壓分三步
| 解壓 | |
| inflateInit(&stream) | 分配記憶體 |
| inflate(&stream, Z_NO_FLUSH); | 解壓數據 |
| inflateEnd(stream); | 釋放記憶體 |
| 返回碼 | |
| #define Z_OK 0 | 壓縮操作成功 |
| #define Z_STREAM_END 1 | 輸入資料已經被完全壓縮,並且壓縮器處於結束狀態。 |
| #define Z_NEED_DICT 2 | 愛密碼 |
| #define Z_ERRNO (-1) | |
| #define Z_STREAM_ERROR (-2) | |
| #define Z_DATA_ERROR (-3) | 加密數據損壞壞,或缺失. |
| #define Z_MEM_ERROR (-4) | 唔夠記憶體 |
| #define Z_BUF_ERROR (-5) | 唔夠緩存 |
| #define Z_VERSION_ERROR (-6) |
解壓示例
int Uncompress_Data_gZip(PBYTE dest,int * dest_length,PBYTE sour,int sour_length)
{
z_stream stream;
int ret;
stream.zalloc = (alloc_func)0;
stream.zfree = (free_func)0;
stream.opaque = (voidpf)0;
stream.next_in = (Bytef*)sour;
stream.avail_in = (uInt)sour_length;
stream.next_out = dest;
stream.avail_out = (uInt)*dest_length;
MAX_MEM_LEVEL
ret = inflateInit2(&stream, 16+MAX_WBITS);
if (ret != Z_OK)
return ret;
ret = inflate(&stream, Z_NO_FLUSH);// 解壓
*dest_length = stream.total_out;
inflateEnd(&stream);
return ret;
}
壓縮示例
bool Compress_Data_gZip(PBYTE dest,int * dest_length,PBYTE sour,int sour_length, int level)
{
int ret;
int flush;
//int sour_offset,dest_offset;
//int have;
z_stream stream;
//BYTE in[ZIP_CHUNK];
//BYTE out[ZIP_CHUNK];
stream.zalloc = Z_NULL;// 記憶體分配函數
stream.zfree = Z_NULL;// 記憶體釋放函數
stream.opaque = Z_NULL;
stream.next_in = (Bytef*)sour; // 輸入
stream.avail_in = (uInt)sour_length;
stream.next_out = dest;//輸出
stream.avail_out = (uInt)*dest_length;
ret = deflateInit(&stream, level);// 内存分配
if (ret != Z_OK)
return false;
flush = Z_FINISH;
//flush = Z_NO_FLUSH;// 允許壓縮演算法決定累積多少資料再產生輸出,以達到壓縮效率最高.
while (ret == Z_OK) {
ret = deflate(&stream, flush); // 進行壓縮
if (ret == Z_STREAM_END)
break;
else
if (ret == Z_BUF_ERROR)//緩衝吾够
break;
else
if (ret == Z_STREAM_ERROR)// 內部錯誤
break;
}
*dest_length = stream.total_out;
deflateEnd(&stream);// 釋放記憶體
return Z_OK;
}
