5

我正在寻找一种方法来获取使用 xz 实用程序压缩的 LZMA2 / .xz 文件的未压缩流大小。

我正在使用 Windows/Linux 中的 liblzma 来完成这项任务,所以我想我正在 liblzma 中寻找一些可以解决问题的 C/C++ API。

4

2 回答 2

6

我想我找到了解决办法。

这是一个非常粗略的代码示例,但似乎工作正常。

我假设我有一个 do_mmap() 函数,它将整个文件作为只读映射到内存中,并返回映射的总大小。这自然可以适应使用 read/fread/ReadFile 或任何其他 File API。

extern size_t get_uncompressed_size(const char *filename)
{
   lzma_stream_flags stream_flags;
   int file_size;

   const uint8_t *data = (uint8_t *) do_mmap(filename, &file_size);

   // 12 is the size of the footer per the file-spec...
   const uint8_t *footer_ptr = data + file_size - 12;

   // Something is terribly wrong
   if (footer_ptr < data) {
     do_unmap((void *)data, file_size);
     return -1;
   }

   // Decode the footer, so we have the backward_size pointing to the index
   lzma_stream_footer_decode(&stream_flags, (const uint8_t *)footer_ptr);
   // This is the index pointer, where the size is ultimately stored...
   const uint8_t *index_ptr = footer_ptr - stream_flags.backward_size;
   // Allocate an index
   lzma_index *index = lzma_index_init(NULL);
   uint64_t memlimit;
   size_t in_pos = 0;
   // decode the index we calculated
   lzma_index_buffer_decode(&index, &memlimit, NULL, index_ptr, &in_pos, footer_ptr - index_ptr);
   // Just make sure the whole index was decoded, otherwise, we might be
   // dealing with something utterly corrupt
   if (in_pos != stream_flags.backward_size) {
     do_unmap((void *)data, file_size);
     lzma_index_end(index, NULL);
     return -1;
   }
   // Finally get the size
   lzma_vli uSize = lzma_index_uncompressed_size(index);
   lzma_index_end(index, NULL);
   return (size_t) uSize;
}
于 2010-02-01T02:32:55.000 回答
0

从sourceforge下载源代码并查看这里,我从主头文件LzmaLib.h中引用了它

/*
Lzma解压缩
--------------
在:
  dest - 输出数据
  destLen - 输出数据大小
  src - 输入数据
  srcLen - 输入数据大小
出去:
  destLen - 处理后的输出大小
  srcLen - 处理后的输入大小
回报:
  SZ_OK - 好的
  SZ_ERROR_DATA - 数据错误
  SZ_ERROR_MEM - 内存分配错误
  SZ_ERROR_UNSUPPORTED - 不支持的属性
  SZ_ERROR_INPUT_EOF - 它需要输入缓冲区(src)中的更多字节
*/

MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
  const unsigned char *props, size_t propsSize);

看起来这destLen是未压缩数据的大小。

希望这会有所帮助,最好的问候,汤姆。

于 2010-01-31T13:29:24.317 回答