miniz:Google开源库,它是单一的C源文件,紧缩/膨胀压缩库,使用zlib兼容API,ZIP归档读写,PNG写方式。关于miniz的更详细介绍可以参考:https://code.google.com/archive/p/miniz/

miniz.c is a lossless, high performance data compression library in a single source file that implements the zlib(RFC 1950) and Deflate(RFC 1951) compressed data format specification standards.

miniz.c also contains simple to use functions for writing .PNG format image files and reading/writing/appending .ZIP format archives.

从https://github.com/richgel999/miniz下载源代码,也可以从google下载:https://code.google.com/archive/p/miniz/downloads。

测试miniz的使用,新建miniz_Test控制台工程,测试代码(来源于源代码中的example*.c文件)如下:

#include "funset.hpp"
#include "../../src/miniz/miniz.c"

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint;

#define my_max(a,b) (((a) > (b)) ? (a) : (b))
#define my_min(a,b) (((a) < (b)) ? (a) : (b))

#define BUF_SIZE (1024 * 1024)

// Demonstrates miniz.c's compress() and uncompress() functions (same as zlib's),
// also a crude decompressor fuzzy test.
int test_miniz_1()
{
	// The string to compress.
	static const char *s_pStr = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
		"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
		"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
		"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
		"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
		"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
		"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson.";

	uint step = 0;
	int cmp_status;
	uLong src_len = (uLong)strlen(s_pStr);
	uLong cmp_len = compressBound(src_len);
	uLong uncomp_len = src_len;
	uint8 *pCmp, *pUncomp;
	uint total_succeeded = 0;

	printf("miniz.c version: %s\n", MZ_VERSION);

	do {
		// Allocate buffers to hold compressed and uncompressed data.
		pCmp = (mz_uint8 *)malloc((size_t)cmp_len);
		pUncomp = (mz_uint8 *)malloc((size_t)src_len);
		if ((!pCmp) || (!pUncomp)) {
			printf("Out of memory!\n");
			return EXIT_FAILURE;
		}

		// Compress the string.
		cmp_status = compress(pCmp, &cmp_len, (const unsigned char *)s_pStr, src_len);
		if (cmp_status != Z_OK) {
			printf("compress() failed!\n");
			free(pCmp);
			free(pUncomp);
			return EXIT_FAILURE;
		}

		printf("Compressed from %u to %u bytes\n", (mz_uint32)src_len, (mz_uint32)cmp_len);

		if (step) {
			// Purposely corrupt the compressed data if fuzzy testing (this is a very crude fuzzy test).
			uint n = 1 + (rand() % 3);
			while (n--) {
				uint i = rand() % cmp_len;
				pCmp[i] ^= (rand() & 0xFF);
			}
		}

		// Decompress.
		cmp_status = uncompress(pUncomp, &uncomp_len, pCmp, cmp_len);
		total_succeeded += (cmp_status == Z_OK);

		if (step) {
			printf("Simple fuzzy test: step %u total_succeeded: %u\n", step, total_succeeded);
		} else {
			if (cmp_status != Z_OK) {
				printf("uncompress failed!\n");
				free(pCmp);
				free(pUncomp);
				return EXIT_FAILURE;
			}

			printf("Decompressed from %u to %u bytes\n", (mz_uint32)cmp_len, (mz_uint32)uncomp_len);

			// Ensure uncompress() returned the expected data.
			if ((uncomp_len != src_len) || (memcmp(pUncomp, s_pStr, (size_t)src_len))) {
				printf("Decompression failed!\n");
				free(pCmp);
				free(pUncomp);
				return EXIT_FAILURE;
			}
		}

		free(pCmp);
		free(pUncomp);

		step++;

		// Keep on fuzzy testing if there's a non-empty command line.
	} while (step <= 2);

	printf("Success.\n");
	return EXIT_SUCCESS;
}

// Demonstration of miniz.c's ZIP archive API's. Adds a bunch of filesto test.zip,
// dumps file stat info on each file in the archive, then extracts a single file into memory.
int test_miniz_2()
{
	// The string to compress.
	static const char *s_pTest_str =
		"MISSION CONTROL I wouldn't worry too much about the computer. First of all, there is still a chance that he is right, despite your tests, and" \
		"if it should happen again, we suggest eliminating this possibility by allowing the unit to remain in place and seeing whether or not it" \
		"actually fails. If the computer should turn out to be wrong, the situation is still not alarming. The type of obsessional error he may be" \
		"guilty of is not unknown among the latest generation of HAL 9000 computers. It has almost always revolved around a single detail, such as" \
		"the one you have described, and it has never interfered with the integrity or reliability of the computer's performance in other areas." \
		"No one is certain of the cause of this kind of malfunctioning. It may be over-programming, but it could also be any number of reasons. In any" \
		"event, it is somewhat analogous to human neurotic behavior. Does this answer your query?  Zero-five-three-Zero, MC, transmission concluded.";

	static const char *s_pComment = "This is a comment";

	int i, sort_iter;
	mz_bool status;
	size_t uncomp_size;
	mz_zip_archive zip_archive;
	void *p;
	const int N = 5; //50;
	char data[2048];
	char archive_filename[64];
	static const char *s_Test_archive_filename = "E:/GitCode/Messy_Test/testdata/miniz2.zip";

	assert((strlen(s_pTest_str) + 64) < sizeof(data));

	printf("miniz.c version: %s\n", MZ_VERSION);

	// Delete the test archive, so it doesn't keep growing as we run this test
	remove(s_Test_archive_filename);

	// Append a bunch of text files to the test archive
	for (i = (N - 1); i >= 0; --i) {
		sprintf(archive_filename, "%u.txt", i);
		sprintf(data, "%u %s %u", (N - 1) - i, s_pTest_str, i);

		// Add a new file to the archive. Note this is an IN-PLACE operation, so if it fails your archive is probably hosed (its central directory may not be complete) but it should be recoverable using zip -F or -FF. So use caution with this guy.
		// A more robust way to add a file to an archive would be to read it into memory, perform the operation, then write a new archive out to a temp file and then delete/rename the files.
		// Or, write a new archive to disk to a temp file, then delete/rename the files. For this test this API is fine.
		status = mz_zip_add_mem_to_archive_file_in_place(s_Test_archive_filename, archive_filename, data, strlen(data) + 1, s_pComment, (uint16)strlen(s_pComment), MZ_BEST_COMPRESSION);
		if (!status) {
			printf("mz_zip_add_mem_to_archive_file_in_place failed!\n");
			return EXIT_FAILURE;
		}
	}

	// Add a directory entry for testing
	status = mz_zip_add_mem_to_archive_file_in_place(s_Test_archive_filename, "directory/", NULL, 0, "no comment", (uint16)strlen("no comment"), MZ_BEST_COMPRESSION);
	if (!status) {
		printf("mz_zip_add_mem_to_archive_file_in_place failed!\n");
		return EXIT_FAILURE;
	}

	// Now try to open the archive.
	memset(&zip_archive, 0, sizeof(zip_archive));

	status = mz_zip_reader_init_file(&zip_archive, s_Test_archive_filename, 0);
	if (!status) {
		printf("mz_zip_reader_init_file() failed!\n");
		return EXIT_FAILURE;
	}

	// Get and print information about each file in the archive.
	for (i = 0; i < (int)mz_zip_reader_get_num_files(&zip_archive); i++) {
		mz_zip_archive_file_stat file_stat;
		if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat)) {
			printf("mz_zip_reader_file_stat() failed!\n");
			mz_zip_reader_end(&zip_archive);
			return EXIT_FAILURE;
		}

		printf("Filename: \"%s\", Comment: \"%s\", Uncompressed size: %u, Compressed size: %u, Is Dir: %u\n", file_stat.m_filename, file_stat.m_comment, (uint)file_stat.m_uncomp_size, (uint)file_stat.m_comp_size, mz_zip_reader_is_file_a_directory(&zip_archive, i));

		if (!strcmp(file_stat.m_filename, "directory/")) {
			if (!mz_zip_reader_is_file_a_directory(&zip_archive, i)) {
				printf("mz_zip_reader_is_file_a_directory() didn't return the expected results!\n");
				mz_zip_reader_end(&zip_archive);
				return EXIT_FAILURE;
			}
		}
	}

	// Close the archive, freeing any resources it was using
	mz_zip_reader_end(&zip_archive);

	// Now verify the compressed data
	for (sort_iter = 0; sort_iter < 2; sort_iter++) {
		memset(&zip_archive, 0, sizeof(zip_archive));
		status = mz_zip_reader_init_file(&zip_archive, s_Test_archive_filename, sort_iter ? MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY : 0);
		if (!status) {
			printf("mz_zip_reader_init_file() failed!\n");
			return EXIT_FAILURE;
		}

		for (i = 0; i < N; i++) {
			sprintf(archive_filename, "%u.txt", i);
			sprintf(data, "%u %s %u", (N - 1) - i, s_pTest_str, i);

			// Try to extract all the files to the heap.
			p = mz_zip_reader_extract_file_to_heap(&zip_archive, archive_filename, &uncomp_size, 0);
			if (!p) {
				printf("mz_zip_reader_extract_file_to_heap() failed!\n");
				mz_zip_reader_end(&zip_archive);
				return EXIT_FAILURE;
			}

			// Make sure the extraction really succeeded.
			if ((uncomp_size != (strlen(data) + 1)) || (memcmp(p, data, strlen(data)))) {
				printf("mz_zip_reader_extract_file_to_heap() failed to extract the proper data\n");
				mz_free(p);
				mz_zip_reader_end(&zip_archive);
				return EXIT_FAILURE;
			}

			printf("Successfully extracted file \"%s\", size %u\n", archive_filename, (uint)uncomp_size);
			printf("File data: \"%s\"\n", (const char *)p);

			// We're done.
			mz_free(p);
		}

		// Close the archive, freeing any resources it was using
		mz_zip_reader_end(&zip_archive);
	}

	printf("Success.\n");
	return EXIT_SUCCESS;
}

// Demonstrates how to use miniz.c's deflate() and inflate() functions for simple file compression.
// Command line tool for file compression/decompression.
int test_miniz_3()
{
	static uint8 s_inbuf[BUF_SIZE];
	static uint8 s_outbuf[BUF_SIZE];

	const char *pMode;
	FILE *pInfile, *pOutfile;
	uint infile_size;
	int level = Z_BEST_COMPRESSION;
	z_stream stream;
	int p = 1;
	const char *pSrc_filename;
	const char *pDst_filename;
	long file_loc;

	printf("miniz.c version: %s\n", MZ_VERSION);

	int argc = 5;
	char* argv[5] {"", "-l5", "c", "E:/GitCode/Messy_Test/testdata/infile.zip", "E:/GitCode/Messy_Test/testdata/outfile_compress.zip"};
	//char* argv[5] {"", "-l5", "d", "E:/GitCode/Messy_Test/testdata/outfile_compress.zip", "E:/GitCode/Messy_Test/testdata/outfile_decompress.zip"};

	if (argc < 4) {
		printf("Usage: example3 [options] [mode:c or d] infile outfile\n");
		printf("\nModes:\n");
		printf("c - Compresses file infile to a zlib stream in file outfile\n");
		printf("d - Decompress zlib stream in file infile to file outfile\n");
		printf("\nOptions:\n");
		printf("-l[0-10] - Compression level, higher values are slower.\n");
		return EXIT_FAILURE;
	}

	while ((p < argc) && (argv[p][0] == '-')) {
		switch (argv[p][1]) {
			case 'l': {
				level = atoi(&argv[1][2]);
				if ((level < 0) || (level > 10)) {
					printf("Invalid level!\n");
					return EXIT_FAILURE;
				}
				break;
			}
			default: {
				printf("Invalid option: %s\n", argv[p]);
				return EXIT_FAILURE;
			}
		}
		p++;
	}

	if ((argc - p) < 3) {
		printf("Must specify mode, input filename, and output filename after options!\n");
		return EXIT_FAILURE;
	} else if ((argc - p) > 3) {
		printf("Too many filenames!\n");
		return EXIT_FAILURE;
	}

	pMode = argv[p++];
	if (!strchr("cCdD", pMode[0])) {
		printf("Invalid mode!\n");
		return EXIT_FAILURE;
	}

	pSrc_filename = argv[p++];
	pDst_filename = argv[p++];

	printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename);

	// Open input file.
	pInfile = fopen(pSrc_filename, "rb");
	if (!pInfile) {
		printf("Failed opening input file!\n");
		return EXIT_FAILURE;
	}

	// Determine input file's size.
	fseek(pInfile, 0, SEEK_END);
	file_loc = ftell(pInfile);
	fseek(pInfile, 0, SEEK_SET);

	if ((file_loc < 0) || (file_loc > INT_MAX)) {
		// This is not a limitation of miniz or tinfl, but this example.
		printf("File is too large to be processed by this example.\n");
		return EXIT_FAILURE;
	}

	infile_size = (uint)file_loc;

	// Open output file.
	pOutfile = fopen(pDst_filename, "wb");
	if (!pOutfile) {
		printf("Failed opening output file!\n");
		return EXIT_FAILURE;
	}

	printf("Input file size: %u\n", infile_size);

	// Init the z_stream
	memset(&stream, 0, sizeof(stream));
	stream.next_in = s_inbuf;
	stream.avail_in = 0;
	stream.next_out = s_outbuf;
	stream.avail_out = BUF_SIZE;

	if ((pMode[0] == 'c') || (pMode[0] == 'C')) {
		// Compression.
		uint infile_remaining = infile_size;

		if (deflateInit(&stream, level) != Z_OK) {
			printf("deflateInit() failed!\n");
			return EXIT_FAILURE;
		}

		for (;;) {
			int status;
			if (!stream.avail_in) {
				// Input buffer is empty, so read more bytes from input file.
				uint n = my_min(BUF_SIZE, infile_remaining);

				if (fread(s_inbuf, 1, n, pInfile) != n) {
					printf("Failed reading from input file!\n");
					return EXIT_FAILURE;
				}

				stream.next_in = s_inbuf;
				stream.avail_in = n;

				infile_remaining -= n;
				//printf("Input bytes remaining: %u\n", infile_remaining);
			}

			status = deflate(&stream, infile_remaining ? Z_NO_FLUSH : Z_FINISH);

			if ((status == Z_STREAM_END) || (!stream.avail_out)) {
				// Output buffer is full, or compression is done, so write buffer to output file.
				uint n = BUF_SIZE - stream.avail_out;
				if (fwrite(s_outbuf, 1, n, pOutfile) != n) {
					printf("Failed writing to output file!\n");
					return EXIT_FAILURE;
				}
				stream.next_out = s_outbuf;
				stream.avail_out = BUF_SIZE;
			}

			if (status == Z_STREAM_END)
				break;
			else if (status != Z_OK) {
				printf("deflate() failed with status %i!\n", status);
				return EXIT_FAILURE;
			}
		}

		if (deflateEnd(&stream) != Z_OK) {
			printf("deflateEnd() failed!\n");
			return EXIT_FAILURE;
		}
	} else if ((pMode[0] == 'd') || (pMode[0] == 'D')) {
		// Decompression.
		uint infile_remaining = infile_size;

		if (inflateInit(&stream)) {
			printf("inflateInit() failed!\n");
			return EXIT_FAILURE;
		}

		for (;;) {
			int status;
			if (!stream.avail_in) {
				// Input buffer is empty, so read more bytes from input file.
				uint n = my_min(BUF_SIZE, infile_remaining);

				if (fread(s_inbuf, 1, n, pInfile) != n) {
					printf("Failed reading from input file!\n");
					return EXIT_FAILURE;
				}

				stream.next_in = s_inbuf;
				stream.avail_in = n;

				infile_remaining -= n;
			}

			status = inflate(&stream, Z_SYNC_FLUSH);

			if ((status == Z_STREAM_END) || (!stream.avail_out)) {
				// Output buffer is full, or decompression is done, so write buffer to output file.
				uint n = BUF_SIZE - stream.avail_out;
				if (fwrite(s_outbuf, 1, n, pOutfile) != n) {
					printf("Failed writing to output file!\n");
					return EXIT_FAILURE;
				}
				stream.next_out = s_outbuf;
				stream.avail_out = BUF_SIZE;
			}

			if (status == Z_STREAM_END)
				break;
			else if (status != Z_OK) {
				printf("inflate() failed with status %i!\n", status);
				return EXIT_FAILURE;
			}
		}

		if (inflateEnd(&stream) != Z_OK) {
			printf("inflateEnd() failed!\n");
			return EXIT_FAILURE;
		}
	} else {
		printf("Invalid mode!\n");
		return EXIT_FAILURE;
	}

	fclose(pInfile);
	if (EOF == fclose(pOutfile)) {
		printf("Failed writing to output file!\n");
		return EXIT_FAILURE;
	}

	printf("Total input bytes: %u\n", (mz_uint32)stream.total_in);
	printf("Total output bytes: %u\n", (mz_uint32)stream.total_out);
	printf("Success.\n");
	return EXIT_SUCCESS;
}

// Uses tinfl.c to decompress a zlib stream in memory to an output file
int test_miniz_4()
{
	// need include "tinfl.c", conflict with "miniz.c"
	// reference: example4.c
	return 0;
}

// Demonstrates how to use miniz.c's low-level tdefl_compress() and tinfl_inflate() API's for simple file to file compression/decompression.
// The low-level API's are the fastest, make no use of dynamic memory allocation, and are the most flexible functions exposed by miniz.c.
int test_miniz_5()
{
	// reference: example5.c
	// conflict with other examples(1/2/3)
	return 0;
}

// Demonstrates how to miniz's PNG writer func
int test_miniz_6()
{
	// reference: example6.c
	// conflict with other examples(1/2/3)
	return 0;
}

GitHub:https://github.com/fengbingchun/Messy_Test

miniz库简介及使用的更多相关文章

  1. BerkeleyDB库简介

    BerkeleyDB库简介 BerkeleyDB(简称为BDB)是一种以key-value为结构的嵌入式数据库引擎: 嵌入式:bdb提供了一系列应用程序接口(API),调用这些接口很简单,应用程序和b ...

  2. LevelDB库简介

    LevelDB库简介 一.LevelDB入门 LevelDB是Google开源的持久化KV单机数据库,具有很高的随机写,顺序读/写性能,但是随机读的性能很一般,也就是说,LevelDB很适合应用在查询 ...

  3. MXNet深度学习库简介

    MXNet深度学习库简介 摘要: MXNet是一个深度学习库, 支持C++, Python, R, Scala, Julia, Matlab以及JavaScript等语言; 支持命令和符号编程; 可以 ...

  4. Python3.x:第三方库简介

    Python3.x:第三方库简介 环境管理 管理 Python 版本和环境的工具 p – 非常简单的交互式 python 版本管理工具. pyenv – 简单的 Python 版本管理工具. Vex ...

  5. php spl标准库简介(SPL是Standard PHP Library(PHP标准库)(直接看代码实例,特别方便)

    php spl标准库简介(SPL是Standard PHP Library(PHP标准库)(直接看代码实例,特别方便) 一.总结 直接看代码实例,特别方便易懂 thinkphp控制器利眠宁不支持(说明 ...

  6. 免费淘宝IP地址库简介及PHP/C#调用实例

    https://yq.aliyun.com/ziliao/25800?spm=a2c4e.11155472.0.0.68027abfcpFb7O 摘要: 本文讲的是免费淘宝IP地址库简介及PHP/C# ...

  7. c++模板库(简介)

    目 录 STL 简介 ......................................................................................... ...

  8. css公共库——简介中超过长度显示省略号

    在简介.引言中常见:文字只有一排,超出宽度以省略号显示,像这样 实现方法:在公共库定义otw类 .otw{ overflow: hidden; text-overflow: ellipsis; whi ...

  9. java.util.stream 库简介

    Java Stream简介 Java SE 8 中主要的新语言特性是拉姆达表达式.可以将拉姆达表达式想作一种匿名方法:像方法一样,拉姆达表达式具有带类型的参数.主体和返回类型.但真正的亮点不是拉姆达表 ...

随机推荐

  1. 51nod 1832 先序遍历与后序遍历【二叉树+高精度】

    题目链接:51nod 1832 先序遍历与后序遍历 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 对于给定的一个二叉树的先序遍历和后序遍历,输出有多少种满足条件的 ...

  2. Windows与kali双系统安装启动项的选择问题

    在安装kali的时候,选择了用linux的grub启动,但是在重启后发现启动项里已经没有Windows系统可以选择了. 网上资料说,进入kali的终端,输入以下命令: $ sudo update-gr ...

  3. [转]Javascript 取小数点后面N位

    用Javascript取float型小数点后两位,例22.127456取成22.13,如何做? 1. 最笨的办法....... [我就怎么干的.........] }  2. 正则表达式效果不错 &l ...

  4. [转]解決 IE10 瀏覽器無法使用 ASP.NET 表單驗證登入的問題

    今天凌晨在客戶端上線,當程式佈署到正式機後發現我們的網站唯獨只有 IE10 瀏覽器無法成功登入,任何其他瀏覽器版本或使用較低的 IE 版本都可以正常登入,使用 IE 相容性檢視也都可以正常登入,想說會 ...

  5. Css animation 与 float 、flex 布局问题

    1. 有这样一段css html 代码 <div class="container"> <div class="float-left"> ...

  6. wpf中使用cefsharp加载本地html网页并实现cs和js的交互,并且cefsharp支持any cpu

    废话少说,直接上代码: 第一步: 第二步: 第三步: 第四步: App.xaml.cs对应的代码: using CefSharp; using CefSharp.Wpf; using System; ...

  7. Spring的入门学习笔记 (注解)

    Spring的bean管理(注解) 注解 1.代码里面特殊标记(ep:@Test),使用注解完成一些相关功能 2.注解写法 @注解名称(属性名称=属性值) 3.可以用在类,方法,属性上都可以 4.Sp ...

  8. linux 学习第八天

    一.特殊权限 1.SUID 让命令的执行者临时获取到了所有者权限(rws) 2.SGID 让目录中新的文件的所有组,归属上级目录 3.SBIT 粘滞位 让目录内的文件只能被文件所有者删除 4.修改文件 ...

  9. 从tomcat下载文件的配置方法(很全呢)

    前几天我做的项目有个下载文件的东西让我苦恼了一下,上传的文件没有放到OSS服务器,而是直接放到tomcat内, 我就想做一个a标签直接下载的得了,结果点开一直都说没有该文件,我查了很多资料找到了如何配 ...

  10. 对布局定位设置-position

    使用position属性,会激活5个属性 left right bottom top z-index(-1至999) 注:z-index:会改变内容的层级关系, 1.绝对定位 position: ab ...