准备写个小说阅读器可以阅读 txt/umd 格式的小说. umd 文件解码想用ndk 用C实现.umd文件格式网上有很多..
由于Umd文件正文部分是用zip压缩的.但是又没有记录解压后的长度.
这样如果使用zlib.h文件中 uncompress方法,需要足够长的空间容纳解压数据,不然就会出错了.郁闷
而且uncompressed又没有compress那样的compressBound的函数可以使用.
看了下源码中的 zpipe.c 感觉还是可以改改的.
struct Output {
//解压后的缓存
char *destBuf;
char *destPos;
//解压后缓存大小
int destLen;
//解压缓存最大容量
int destSize;
} Output;
typedef struct Output Z_out;
int uncompress2(char *src, int srcLen, Z_out &output) {
int ret;
z_stream strm;
/* 解压状态初始化 */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK) {
return ret;
}
strm.avail_in = srcLen;
strm.next_in = (Bytef*)src;
//如果原来没有可用的解压空间
if (!output.destSize) {
output.destSize = srcLen;
output.destBuf = (char*) malloc(srcLen);
}
output.destPos = output.destBuf;
output.destLen = 0;
//循环取出所有内容
do {
strm.avail_out = output.destSize - output.destLen;
strm.next_out = (Bytef*)output.destPos;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR);
//出错状态:
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void) inflateEnd(&strm);
return ret;
}
output.destLen = output.destSize - strm.avail_out;
//解压未结束: 存储空间不足
if (ret != Z_STREAM_END) {
//存储翻倍
output.destSize <<= 1;
//重新申请内存 .... 使用 realloc的缺陷自己解决吧..
output.destBuf = (char*) realloc(output.destBuf, output.destSize);
//位置设定
output.destPos = output.destBuf + output.destLen;
}
} while (ret != Z_STREAM_END);
(void) inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
如有不妥请多多指教.
顺便有 zlib 的c语言源码