1.简介
zlib是一个广泛使用的压缩库,它提供了一系列的函数用于压缩和解压缩数据。zlib使用DEFLATE压缩算法,这是一种无损压缩算法,通常与gzip和zip文件格式一起使用。zlib库本身支持的压缩文件格式是它自己的专有格式,通常用于数据流的无损压缩。这种格式不是一种标准的文件格式,而是一种内存中的压缩数据表示,常用于网络传输、数据库和应用程序内部的数据压缩。
zlib库通常用于:
- 压缩网络传输数据以减少带宽使用。
- 压缩存储数据以减少所需的存储空间。
2.接口介绍
压缩数据
int compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
参数说明:
- dest:指向用于存储压缩数据的缓冲区的指针。
- destLen:一个指向uLongf类型变量的指针,该变量在调用函数前应包含dest缓冲区的大小,在函数返回时将包含压缩数据的实际长度。
- source:指向要压缩的数据的指针。
- sourceLen:要压缩的数据的长度。
返回值:
- Z_OK:压缩成功。
- Z_MEM_ERROR:内存不足,无法进行压缩。
- Z_BUF_ERROR:提供的dest缓冲区太小,无法存储压缩数据。
使用compress函数时,你需要确保dest缓冲区足够大以存储压缩后的数据。通常,压缩后的数据长度不会超过源数据长度的0.001倍加上12字节。因此,你可以按照以下方式分配dest缓冲区的大小:
uLongf destLen = sourceLen * 1.001 + 12;
Bytef *dest = (Bytef *)malloc(destLen);
解压缩数据
int uncompress(Bytef* dest, uLongf* destLen, const Bytef* source, uLong sourceLen);
- dest:指向存放解压缩后数据的缓冲区的指针。
- destLen:传入时为解压缩缓冲区的大小,传出时为实际解压缩后数据的大小。
- source:指向待解压缩数据的缓冲区的指针。
- sourceLen:待解压缩数据的大小。
返回值:
- Z_OK:解压缩成功。
- Z_MEM_ERROR:内存分配失败。
- Z_BUF_ERROR:解压缩输出缓冲区不足。
- Z_DATA_ERROR:输入数据错误或损坏。
3.环境搭建
下载地址:https://github.com/madler/zlib/tree/v1.3
解压后使用cmake编译:
生成库:
拷贝生成的库文件,和zconf.h、zlib.h文件到我们的工程目录下。
配置visual studio环境。
具体看Jsoncpp介绍
4.示例
示例1:压缩/解压缩数据:。
#include <iostream>
#include <zlib.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <vector>
#define CHUNK 16384
using namespace std;
int main()
{
const char* input = "This is a string that we want to compress.This is a string that we want to compress";
unsigned long sourceLen = strlen(input);
unsigned char* compressed = NULL;
unsigned long compressedLen = sourceLen * 1.001 + 12;
compressed = (unsigned char*)realloc(compressed,compressedLen);
if (compressed == NULL)
{
printf("Failed to allocate memory for compressed data.\n");
return -1;
}
// 压缩数据
int ret = compress(compressed, &compressedLen, (const Bytef*)input, sourceLen);
if (Z_OK == ret)
{
printf("compress success!!!\n");
printf("Original size: %lu\n", sourceLen);
printf("Compressed size: %lu\n", compressedLen);
}
unsigned char* decompressed = NULL;
unsigned long decompressedLen = sourceLen;
decompressed = (unsigned char*)realloc(decompressed,decompressedLen);
// 解压缩数据
uncompress(decompressed, &decompressedLen, compressed, compressedLen);
printf("Decompressed string: %s\n", decompressed);
// 释放内存
free(compressed);
return 0;
}
运行截图:
示例2:压缩/解压缩文件
#include <iostream>
#include <zlib.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <vector>
using namespace std;
bool compressFile(const std::string& sourceFilename, const std::string& compressedFilename)
{
std::ifstream source(sourceFilename, std::ios_base::binary);
std::ofstream dest(compressedFilename, std::ios_base::binary);
if (!source || !dest)
{
std::cerr << "Could not open source or destination file." << std::endl;
return false;
}
z_stream zs;
memset(&zs, 0, sizeof(zs));
if (deflateInit(&zs, Z_DEFAULT_COMPRESSION) != Z_OK)
{
std::cerr << "deflateInit failed while compressing." << std::endl;
return false;
}
// 压缩缓冲区
const size_t bufSize = 128 * 1024;
std::vector<char> inBuffer(bufSize);
std::vector<char> outBuffer(bufSize);
int deflateStatus;
do
{
// 读取源文件内容到缓冲区
source.read(inBuffer.data(), inBuffer.size());
zs.next_in = reinterpret_cast<Bytef*>(inBuffer.data());
zs.avail_in = source.gcount(); //实际读取字节数
do
{
zs.next_out = reinterpret_cast<Bytef*>(outBuffer.data());
zs.avail_out = outBuffer.size(); //next_out剩余可用空间
deflateStatus = deflate(&zs, source.eof() ? Z_FINISH : Z_NO_FLUSH);
if (deflateStatus == Z_STREAM_ERROR)
{
std::cerr << "Deflate failed during compression." << std::endl;
deflateEnd(&zs);
return false;
}
// 写入压缩数据到目标文件
int have = outBuffer.size() - zs.avail_out;
dest.write(outBuffer.data(), have);
} while (zs.avail_out == 0);
} while (deflateStatus != Z_STREAM_END);
deflateEnd(&zs);
return true;
}
bool decompressFile(const std::string& compressedFilename, const std::string& destFilename)
{
std::ifstream source(compressedFilename, std::ios_base::binary);
std::ofstream dest(destFilename, std::ios_base::binary);
if (!source || !dest)
{
std::cerr << "Could not open source or destination file." << std::endl;
return false;
}
z_stream zs;
memset(&zs, 0, sizeof(zs));
if (inflateInit(&zs) != Z_OK)
{
std::cerr << "inflateInit failed while decompressing." << std::endl;
return false;
}
const size_t bufSize = 128 * 1024;
std::vector<char> inBuffer(bufSize);
std::vector<char> outBuffer(bufSize);
int inflateStatus;
do
{
source.read(inBuffer.data(), inBuffer.size());
zs.next_in = reinterpret_cast<Bytef*>(inBuffer.data());
zs.avail_in = source.gcount();
do
{
zs.next_out = reinterpret_cast<Bytef*>(outBuffer.data());
zs.avail_out = outBuffer.size();
inflateStatus = inflate(&zs, Z_NO_FLUSH);
if (inflateStatus == Z_NEED_DICT || inflateStatus == Z_DATA_ERROR || inflateStatus == Z_MEM_ERROR)
{
std::cerr << "Inflate failed during decompression." << std::endl;
inflateEnd(&zs);
return false;
}
int have = outBuffer.size() - zs.avail_out;
dest.write(outBuffer.data(), have);
} while (zs.avail_out == 0);
} while (inflateStatus != Z_STREAM_END);
inflateEnd(&zs);
return true;
}
int main()
{
bool ret = compressFile("E:/2.mp4", "E:/2.zlib");
//bool ret = decompressFile("E:/2.zlib", "E:/3.mp4");
return 0;
}
5.更多参考
libVLC 专栏介绍-CSDN博客
Qt+FFmpeg+opengl从零制作视频播放器-1.项目介绍_qt opengl视频播放器-CSDN博客
QCharts -1.概述-CSDN博客
JSON++介绍