如何获取 LZMA2 文件 (.xz / liblzma) 的未压缩大小

发布于 2024-08-19 10:03:46 字数 139 浏览 6 评论 0原文

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

我使用 Windows/Linux 中的 liblzma 来完成此任务,所以我想我正在 liblzma 中寻找一些 C/C++ API 来完成此任务。

I'm looking for a way to get the uncompressed stream size of an LZMA2 / .xz file compressed with the xz utility.

I'm using liblzma from Windows/Linux for this task, so I guess I'm looking for some C/C++ API in liblzma that will do the trick.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

云胡 2024-08-26 10:03:47

我想我已经找到了解决方案。

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

我假设我有一个 do_mmap() 函数,它将整个文件以只读方式映射到内存中,并返回映射的总大小。
这自然可以适应使用 read/fread/ReadFile 或任何其他文件 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;
}

I think I've found a solution.

This is a very crude code sample, but seems to work fine.

I'm assuming I have a do_mmap() function that maps the entire file as read-only into memory, and returns the total size mapped.
This can naturally be adapted to use read/fread/ReadFile or any other 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;
}
旧话新听 2024-08-26 10:03:47

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

/*
LzmaUncompress
--------------
In:
  dest     - output data
  destLen  - output data size
  src      - input data
  srcLen   - input data size
Out:
  destLen  - processed output size
  srcLen   - processed input size
Returns:
  SZ_OK                - OK
  SZ_ERROR_DATA        - Data error
  SZ_ERROR_MEM         - Memory allocation arror
  SZ_ERROR_UNSUPPORTED - Unsupported properties
  SZ_ERROR_INPUT_EOF   - it needs more bytes in input buffer (src)
*/

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

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

Having downloaded the source from sourceforge and had a look here, I quoted this from the main header file LzmaLib.h

/*
LzmaUncompress
--------------
In:
  dest     - output data
  destLen  - output data size
  src      - input data
  srcLen   - input data size
Out:
  destLen  - processed output size
  srcLen   - processed input size
Returns:
  SZ_OK                - OK
  SZ_ERROR_DATA        - Data error
  SZ_ERROR_MEM         - Memory allocation arror
  SZ_ERROR_UNSUPPORTED - Unsupported properties
  SZ_ERROR_INPUT_EOF   - it needs more bytes in input buffer (src)
*/

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

It looks that destLen is the size of the data that is uncompressed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文