Zlib介绍

news2025/1/15 22:59:13

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++介绍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1653895.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【密码学原语介绍】PPRF(可穿孔伪随机函数)

在现代密码学中&#xff0c;伪随机函数&#xff08;PRF&#xff09;是构建各种加密协议和系统的基石。它们提供了一种方式&#xff0c;通过它&#xff0c;给定一个密钥和一个输入&#xff0c;可以生成一个无法预测的伪随机输出。这种机制对于确保数据加密、身份验证和完整性验证…

文件IO-使用dup2实现错误日志功能及判断文件权限,并终端输出

1&#xff1a;使用 dup2 实现错误日志功能 使用 write 和 read 实现文件的拷贝功能&#xff0c;注意&#xff0c;代码中所有函数后面&#xff0c;紧跟perror输出错误信息&#xff0c;要求这些错误信息重定向到错误日志 err.txt 中去 代码&#xff1a; #incl…

分享《2024年中国企业级SaaS行业研究报告》

&#xff08;文章作者与来源&#xff1a;艾瑞咨询&#xff09; 大浪淘沙&#xff0c;SaaS行业进入关键转折点&#xff0c;企业级SaaS的总体市场规模达到888亿元&#xff0c;同比增长13.0%。内外部因素叠加之下&#xff0c;预计三年未来企业级SaaS市场规模的增速将稳定在15%-20…

Java17的崛起——newrelic的2024 年 Java 生态系统状

newrelic 2024 年 Java 生态系统状况 原文PDF&#xff1a;点我下载 生产中最常用的 Java 版本 Oracle 每六个月发布一次新的 Java 版本&#xff08;通常是在 3 月和 9 月&#xff09;&#xff0c;每个版本都包含一些新功能和错误修复。每两年&#xff0c;Oracle 都会推出一…

java--io流(一)

1. 前置知识 字符集是什么&#xff1f; 字符集&#xff08;Character Set&#xff09;是一组字符的集合&#xff0c;它定义了可以在计算机系统中使用的所有字符。字符集可以包括字母、数字、标点符号、控制字符、图形符号等。字符集使得计算机能够存储、处理和显示各种语言和…

Baidu Comate智能编码助手 -----AI编程帮你解放双手

目录 Baidu Comate是什么&#xff1f; Baidu Comate如何安装&#xff1f; 在VSCode上安装Baidu Comate插件 Baidu Comate如何使用&#xff0c;有哪些功能&#xff1f; 1.代码解释 2.代码注释 使用感受 如何体验 Baidu Comate是什么&#xff1f; Baidu Comate智能编码助手…

Comate,一款基于文心大模型的智能编程助手

一、官网 Baidu Comate官网 二、安装VSCode 如何下载安装VSCode 三、VSCode安装Comate 安装方式1 访问Comate官网点击 立即安装Comate插件 按钮快速安装 安装方式2 访问VSCode市场中的BaiduComate 点击 Install 按钮访问扩展详情界面 2.打开VSCode 3.安装Comate 四、…

图像降噪算法 NL-means 介绍

介绍 Non-Local Means 非局部均值降噪算法&#xff0c;简称NLM&#xff0c;该算法来自 2005年论文“A non-local algorithm for image denoising”&#xff1b;该算法是经典的图像降噪算法&#xff0c;是很多降噪算法的参考对比算法。 2014 年&#xff0c;有 NLM衍生算法NLMP…

树莓派4b测量PM2.5

1.GP2Y1010AU0F粉尘传感器连接图 2. GP2Y1010AU0F工作原理 工作原理 传感器中心有个洞可以让空气自由流过,定向发射LED光,通过检测经过空气中灰尘折射过后的光线来判断灰尘的含量。 3.源代码 main.py # coding=UTF-8 import RPi.GPIO as GPIO from ADC import ADS1015…

正点原子i.MX 93开发板,双核A55+M33+NPU,双路RS485FDCAN千兆网,异核/AI/工业开发!

正点原子i.MX 93开发板新品上市&#xff01;双核A55M33NPU&#xff0c;双路RS485&FDCAN&千兆网&#xff0c;异核/AI/工业开发&#xff01; NXP的i.MX系列是一系列面向多媒体和工业应用的ARM架构微处理器。从i.MX6U到i.MX93&#xff0c;这一系列经历了显著的发展&#x…

kubectl_进阶_安全

安全 在前面的学习中&#xff0c;我们知道对于资源对象的操作都是通过 APIServer 进行的&#xff0c;那么集群是怎样知道我们的请求就是合法的请求呢&#xff1f; 这就涉及到k8s的安全相关的知识了。 1. API对象 Kubernetes有一个很基本的特性就是它的所有资源对象都是模型…

TypeScript 基础学习笔记:interface 与 type 的异同

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 TypeScript 学习笔记&#xff1a;interface 与 type 的异同&#x1f3a3; 引言&#x1f680; 快速入门1️⃣ Interface&#xff08;接口&#xff09;&#x1f4cb; 定义&#x1f91d; 实现&#x1f4a1; 特点 2️⃣ Type Al…

深度学习网络:设计、开发和部署

​书籍&#xff1a;Deep Learning Networks: Design, Development and Deployment 作者&#xff1a;Jayakumar Singaram&#xff0c;S. S. Iyengar&#xff0c;Azad M. Madni 出版&#xff1a;Springer书籍下载-《​深度学习网络&#xff1a;设计、开发和部署》该教材为学生和工…

Redis 实战之RDB文件结构

RDB文件结构 databases 部分key_value_pairs 部分value 的编码字符串对象列表对象集合对象哈希表对象有序集合对象INTSET 编码的集合ZIPLIST 编码的列表、哈希表或者有序集合 总结AOF持久化的实现命令追加 AOF 文件的写入与同步小结 在本章之前的内容中&#xff0c; 我们介绍了…

后门通信模型剖析

通信模型剖析 梳理DinodasRAT Linux后门通信模型如下&#xff1a; 发送数据-通信数据结构 #原始数据 20000000e703881435b674f7de23a2f80fe35ac0ba1a46c7d96e08a8747889eacf6b1950#载荷数据 e703881435b674f7de23a2f80fe35ac0ba1a46c7d96e08a8747889eacf6b1950#数据解密 180…

Datasophon基于dinky1.0.1升级到dinky1.0.2

1.首先下载dinky1.0.2版本 dinky1.0.2下载地址 2.关闭dinky1.0.1 3.升级dinky1.0.2 3.1 解压dinky1.0.2.ta.gz tar -xzvf dinky-release-1.16-1.0.2.tar.gz -C /opt/datasophon/rm -rf dinky-release-1.16-1.0.2.tar.gz复制dinky1.0.1的配置文件到dinky1.0.2目录 cp /op…

leetcode91.解码方法(动态规划)

问题描述&#xff1a; 一条包含字母 A-Z 的消息通过以下映射进行了 编码 &#xff1a; A -> "1" B -> "2" ... Z -> "26" 要 解码 已编码的消息&#xff0c;所有数字必须基于上述映射的方法&#xff0c;反向映射回字母&#xff08;可…

难定取舍,静观其变

今&#xff08;2024年5月8日&#xff09;天&#xff0c;本“人民体验官”在推广人民日报官方微博文化产品《带着笑意的眼睛&#xff0c;能看见最美的风景》的同时&#xff0c;还要联系4月初至今期间&#xff0c;与隐藏在《麻辣论坛》幕后的那位昵称“800727”者所爆发的一连串&…

Python:一种强大的编程语言与无限可能

引言 Python是一种易于学习且功能强大的编程语言&#xff0c;它被广泛用于各种领域&#xff0c;包括数据科学、人工智能、Web开发、系统自动化等。Python以其简洁的语法、丰富的库和易于阅读的风格&#xff0c;成为了许多开发者的首选。本文将探讨Python的特性和应用&#xff…

用户下单操作

一&#xff1a;用户下单需求分析和设计&#xff1a; 用户下单业务说明&#xff1a; 在电商系统中&#xff0c;用户是通过下单的方式通知商家&#xff0c;用户已经购买了商品&#xff0c;需要商家进行备货和发货。 用户下单后会产生订单相关数据&#xff0c;订单数据需要能够体…