转载sunnysab :https://blog.csdn.net/sunnysab/article/details/46672949
ZLIB库
ZLIB版本zlib 1.2.11 地址:http://www.zlib.net
- 使用
接口说明
/**
压缩
参数一Bytef *dest:压缩后的字节
参数二uLongf *destLen:压缩后的字节长度
参数三const Bytef *source:待压缩的字节
参数四uLong sourceLen :待压缩的字节长度
**/
int compress (Bytef *dest, uLongf *destLen,const Bytef *source, uLong sourceLen);
/*
根据待压缩长度返回压缩以后的数据长度
*/ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
/**
解压缩
参数一Bytef *dest:解压缩后的字节
参数二uLongf *destLen:解压缩后的字节长度,返回值是实际解压缩以后的长度
参数三const Bytef *source:待解压缩的字节数据
参数四uLong sourceLen :待解压缩的字节长度
**/
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,const Bytef *source, uLong sourceLen));
QT封装的函数
/**
压缩
参数一OutEncodeData:压缩后的数据,返回值QByteArray
参数二InRawData:待压缩的数据
参数三nErrorCode:返回故障码
**/
long ZlibCompress(QByteArray &OutEncodeData,QByteArray InRawData, int *nErrorCode);
/**
解压缩
参数一OutEncodeData:解压缩后的数据,返回值QByteArray
参数二InRawData:待解压缩的数据
参数三nErrorCode:返回值故障码
**/
long ZlibUncompress(QByteArray &OutDecodeData,QByteArray InEncodeData,int *nErrorCode);
/**
根据长度获取长度
**/
int ZlibGetDecodeLength(uLong InRawLength);
/**
根据QByteArray获取压缩解压缩长度
**/
int ZlibGetDecodeLength(QByteArray InRawData);
/*
* 函 数: ZlibGetDecodeLength
* 功 能: 通过要压缩的数据大小,得到压缩后数据的最大大小
* 以此设置缓冲区
* 参 数: uLong InRawLength 压缩前数据大小
*/
int MainWindow::ZlibGetDecodeLength(uLong InRawLength)
{
return compressBound(InRawLength);
}
/*
* 函 数: ZlibGetDecodeLength
* 功 能: 通过要压缩的数据大小,得到压缩后数据的最大大小
* 以此设置缓冲区
* 参 数: QByteArray InRawData 压缩前数据
*
*/
int MainWindow::ZlibGetDecodeLength(QByteArray InRawData)
{
// 注:
// ((QByteArray)"Hello").size() == 5
// 因为当字符串为 QByteArray , '\0' 被忽略
return compressBound(InRawData.length());
}
/*
* 函 数: ZlibCompress
* 功 能: 执行压缩操作
* 参 数: QByteArray &OutEncodeData 压缩后数据
* QByteArray InRawData 要压缩的数据
int * nErrorCode 错误代码
* 说 明: 当 nErrorCode 不为 NULL 时, 若 compress 出错后, 其数据改为
* compress 返回的错误代码. 在 zlib.h 中可以找到.
* 例如: -5 缓冲区长度不够
* 返回值: 类型 long
* 返回压缩后的长度, -1 表示压缩失败, 请检查 *nErrorCode .
*/
long MainWindow::ZlibCompress(QByteArray &OutEncodeData, QByteArray InRawData,
int * nErrorCode = NULL)
{
Bytef *EncodeData = NULL; // 压缩后的数据暂存于此
int nFuncRet = Z_ERRNO; // 随便找个错误代码先填着
long nOutLength = 0;
// 申请最大缓冲区
nOutLength = ZlibGetDecodeLength(InRawData.length());
EncodeData = new Bytef[nOutLength];
if (NULL != EncodeData)
{
// 调用 compress 函数前, nOutLength 要置为缓冲区大小
nFuncRet = compress(EncodeData, (uLongf *)&nOutLength, (Bytef *)InRawData.data(),
InRawData.length());
if (Z_OK == nFuncRet)
{
// 自己设置好长度为好, 省的 '\0' 被截断了
OutEncodeData.append((const char *)EncodeData, nOutLength);
}
else
{
nOutLength = -1;
}
}
delete EncodeData;
// 输出错误代码
if (NULL != nErrorCode)
{
*nErrorCode = nFuncRet;
}
return nOutLength;
}
解压缩函数简介
/*
* 函 数: ZlibUnCompress
* 功 能: 执行解压操作
* 参 数: QByteArray &OutDecodeData 解压后数据
* QByteArray InEncodeData 要解压的数据
int * nErrorCode 错误代码
* 说 明: 当 nErrorCode 不为 NULL 时, 若 uncompress 出错后, 其数据改为
* uncompress 返回的错误代码. 在 zlib.h 中可以找到.
* 例如: -5 缓冲区长度不够
* 返回值: 类型 long
* 返回解压后的长度, -1 表示解压失败, 请检查 *nErrorCode .
*/
long MainWindow::ZlibUncompress(QByteArray &OutDecodeData, QByteArray InEncodeData,
int * nErrorCode = NULL)
{
Bytef *DecodeData = NULL; // 解压后的数据缓冲区
Bytef *EncodeData_Buffer = NULL; // 要解压的数据缓冲区, 后面用memcpy放到这
int nFuncRet = Z_ERRNO;
uLongf nOutLength = 0;
// 说明:
// 如果压缩后大小比之前小, 缓冲区大小应该设置多少?
// 暂且把 ZlibGetDecodeLength 拿来用用, 确保缓冲区够了.
//nOutLength = ZlibGetDecodeLength(InEncodeData.length());
nOutLength = InEncodeData.length()*4; //
qDebug()<<"InEncodeData.length"<<InEncodeData.length();
qDebug()<<"nOutLength"<<nOutLength;
// 为缓冲区申请内存
DecodeData = new Bytef[nOutLength];
EncodeData_Buffer = new Bytef[nOutLength];
if (NULL != DecodeData && NULL != EncodeData_Buffer)
{
// 由于 QByteArray 在 data() 函数中会因为'\0'截断
// (先鄙视一下,那还叫什么字节操作)
// 文档又说,constData() 效率高
// 所以用 constData() 获取地址然后 memcpy 自己复制
memcpy(EncodeData_Buffer, InEncodeData.constData(), InEncodeData.size());
nFuncRet = uncompress(DecodeData, &nOutLength, (Bytef *)EncodeData_Buffer,
InEncodeData.length());
qDebug()<<"nFuncRet"<<nFuncRet;
if (Z_OK == nFuncRet)
{
OutDecodeData.append((const char *)DecodeData, nOutLength);
}
else
{
nOutLength = -1;
}
}
else
{
nOutLength = -1;
}
// 清理 new 产生的内存
if (NULL != DecodeData)
{
delete DecodeData;
}
if (NULL != EncodeData_Buffer)
{
delete EncodeData_Buffer;
}
// 输出错误代码
if (NULL != nErrorCode)
{
*nErrorCode = nFuncRet;
}
return nOutLength;
}
函数调用测试
void MainWindow::on_pushButton_clicked()
{
QString mFileName = "request.xml";
QString mSeqFileName = "sequence.xml";
quint64 totalBytes;
QFile file(mFileName);
QByteArray SendByte;
QByteArray OutByte;
int *errorCode = NULL;
if(!file.open(QFile::ReadOnly))
{
qDebug() << QString("Send file error! Cannot read XmlFile %1(%2).").arg(mFileName).arg(file.errorString());
return;
}
QDataStream out(&SendByte, QIODevice::WriteOnly);
totalBytes = file.size();
out.device()->seek(0);
out<<file.readAll();
file.close();
SendByte.remove(0,4);
qDebug()<<"totalBytes = "<<totalBytes;
qDebug()<<"SendByte = "<<SendByte.toHex();
long outlength = ZlibCompress(OutByte,SendByte,errorCode);
if(outlength != (-1))
{
qDebug()<<"OutByte = "<<OutByte.toHex();
qDebug()<<"outlength = "<<outlength;
}
const char m_code[] = {0x78,0x9C,0x4D,0x4F,0xD1,0x0A,0x83,0x30,0x0C,0x7C,0x1F,0xEC,0x1F,0xA4,0xEF,0x5B,0x5B,0x61,0x30,0x21,0xD6,0xB7,0x7D,0xC1,0xF6,0x2C,0x9D,0x0D,0x52,0xD0,0x46,0x6B,0x75,0xF3,0xEF,0xD7,0x09,0x4A,0xF3,0x94,0xCB,0x5D,0xEE,0x12,0xA8,0xBE,0x7D,0x97,0x2D,0xE8,0x27,0x4B,0xAE,0x64,0xF2,0x2A,0x58,0x86,0xAE,0x21,0x63,0x5D,0x5B,0xB2,0xD7,0xF3,0x71,0xB9,0xB3,0x4A,0x81,0x27,0x0A,0x0A,0x1A,0xEA,0x7B,0x72,0x0A,0xDE,0xB3,0xED,0xFE,0x82,0xDA,0x1A,0x25,0x44,0x7E,0x13,0x42,0xC8,0x58,0xC0,0x53,0x02,0x5A,0x1D,0xF0,0xA3,0xD7,0x54,0x04,0x3C,0x19,0x42,0x58,0x07,0x54,0x13,0x8E,0x73,0x0C,0x44,0xE0,0x1B,0x04,0xBE,0x87,0x58,0x53,0x2F,0xBA,0xB3,0x26,0x2E,0x64,0x34,0xA0,0xD7,0x61,0xBB,0x70,0xD7,0x33,0x05,0x7B,0x1B,0xED,0x8F,0x92,0x45,0x21,0x73,0xE0,0x07,0x05,0x3C,0xF1,0x89,0x68,0x7B,0xE4,0x7C,0xFA,0x01,0xF3,0xF1,0x52,0x91};
QByteArray mInCode;
QByteArray mOutCode;
mInCode.append(m_code,sizeof(m_code));
qDebug()<<"mInCode = "<<mInCode.toHex();
long decodelenth = ZlibUncompress(mOutCode,mInCode,errorCode);
qDebug()<<"decodelenth = "<<decodelenth;
if(decodelenth != (-1))
{
qDebug()<<"mOutCode = "<<mOutCode.toHex();
qDebug()<<"decodelenth = "<<decodelenth;
}
QFile m_SecFile(mSeqFileName);
if(!m_SecFile.open(QFile::WriteOnly)) return;
m_SecFile.resize(0);//清空原有图片内容
m_SecFile.write(mOutCode.data(),mOutCode.size());
m_SecFile.close();
changeXML(mSeqFileName);
//QString m_strType = "";
//if(!parse(mOutCode,m_strType)){
// qDebug() <<"parse error!";
//}
//qDebug() <<"m_strType:"<<m_strType;
}