android 用zlib 解压数据段

准备写个小说阅读器可以阅读 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语言源码

 

你可能感兴趣的:(android 用zlib 解压数据段)