Zlib内存数据压缩和解压缩

前言

现在要将抓图数据传到另外一台计算机,首先要解决的是将BMP数据压缩.
BMP的压缩率是很大的, 如果不压缩,没办法往下做了.
当前Zlib版本是2013年出的1.2.8, 先做个静态库, 将.h和.cpp包进去,封成静态库使用.
然后在测试程序中,写测试代码.
写这个测试工程的感受, 要先看开源库给的测试例程, 找到需要的函数, 再去查资料,才会快速找到一些自己关心,但是还有疑惑的知识点.

测试工程

srcZlibUsage.zip
编译环境 : vc6sp6 + win7x64 + console + staticlib

代码预览

// testZlibStaticLib.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "../ZlibStaticLib/zlib/zlib.h"
#pragma comment(lib, "../bin/Debug/ZlibStaticLib.lib")

ULONG GetBufCheckSum(IN BYTE* pBuf, ULONG ulLen);

int main(int argc, char *argv[])
{
    int iRc = 0;
    ULONG ulIndex = 0;

    ULONG ulLenSrc = 0; ///< 压缩前数据长度
    BYTE* pBufSrc = NULL; ///< 压缩前数据指针
    ULONG ulCheckSumSrc = 0; ///< 压缩前数据校验和

    ULONG ulLenDst = 0; ///< 压缩后数据长度
    BYTE* pBufDst = NULL; ///< 压缩后数据指针
    ULONG ulCheckSumDst = 0; ///< 压缩后数据校验和

    ULONG ulLenUnzip = 0; ///< 解压后数据长度
    BYTE* pBufUnzip = NULL; ///< 解压后数据指针
    ULONG ulCheckSumUnzip = 0; ///< 解压后数据校验和

    do {
        /// 数据压缩前
        ulLenSrc = 0x1ffff;
        pBufSrc = new BYTE[ulLenSrc];
        assert(NULL != pBufSrc);

        /// 数据压缩后
        ulLenDst = compressBound(ulLenSrc); ///< 压缩后长度可估算
        pBufDst = new BYTE[ulLenDst];
        assert(NULL != pBufDst);

        /// 准备压缩用的数据
        for (ulIndex = 0; ulIndex < ulLenSrc; ulIndex++) {
            pBufSrc[ulIndex] = (BYTE)((rand() + ulIndex) % 0xff); ///< 用随机数据填充
        }

        /// 计算压缩前的校验和, 用于还原比对
        ulCheckSumSrc = GetBufCheckSum(pBufSrc, ulLenSrc);

        /// 压缩操作
        if (Z_OK != compress(pBufDst, &ulLenDst, pBufSrc, ulLenSrc)) {
            _tprintf(_T("compress failed\n"));
            break;
        }

        /// 计算压缩后的校验和, 用于传输
        ulCheckSumDst = GetBufCheckSum(pBufDst, ulLenDst);

        /// 解压操作
        ulLenUnzip = ulLenSrc; ///< 自己保存和传输
        pBufUnzip = new BYTE[ulLenUnzip];
        assert(NULL != pBufUnzip);

        if (Z_OK != uncompress(pBufUnzip, &ulLenUnzip, pBufDst, ulLenDst)) {
            _tprintf(_T("uncompress failed\n"));
            break;
        }

        /// 计算解压后的校验和, 和原始数据的校验和比对
        ulCheckSumUnzip = GetBufCheckSum(pBufUnzip, ulLenUnzip);
        _tprintf(_T("zip and unzip %s\n"), (ulCheckSumUnzip == ulCheckSumSrc) ? _T("ok") : _T("error"));

        /// 虽然已经搞定, 还是再比较一下原始数据和解压后数据的数据长度和内容 ^_^
        assert(ulLenUnzip == ulLenSrc);
        iRc = memcmp(pBufSrc, pBufUnzip, ulLenUnzip);
        assert(0 == iRc);
    } while (0);

    /// 释放资源
    if (NULL != pBufSrc) {
        delete [] pBufSrc;
        pBufSrc = NULL;
    }

    if (NULL != pBufDst) {
        delete [] pBufDst;
        pBufDst = NULL;
    }

    if (NULL != pBufUnzip) {
        delete [] pBufUnzip;
        pBufUnzip = NULL;
    }

    /// rs : zip and unzip ok
    system(_T("pause"));
    return 0;
}

ULONG GetBufCheckSum(IN BYTE* pBuf, ULONG ulLen) {
    ULONG ulIndex = 0;
    ULONG ulCheckSumSrc = adler32(0L, Z_NULL, 0);
    const ULONG ulBlockSize = 0xfffffffe;
    ULONG ulBlockCalc = 0;

    /// 循环一块一块的计算校验和
    for (ulIndex = 0; ulIndex < ulLen; ulIndex += ulBlockCalc) {
        ulBlockCalc = ((ulIndex + ulBlockSize) < ulLen) ? ulBlockSize : (ulLen - ulIndex);
        if (ulBlockCalc > 0) {
            /// adler32 可以一段一段的算校验和, 防止要算的长度 > ULONG的最大值
            /// 入参以后可以改成ULONGLONG
            ulCheckSumSrc = adler32(ulCheckSumSrc, pBuf + ulIndex, ulBlockCalc);
            continue;
        }

        break;
    }

    return ulCheckSumSrc;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值