未知的zlib标题(.vrscene)

时间:2012-08-08 15:34:49

标签: zlib compression

这是Vray的.vrscene文件的格式说明: http://spot3d.com/vray/help/maya/sdk22/vrscene_format.html

我对关于“压缩十六进制列表”的段落很感兴趣。据说压缩列表等于标题(“ZIPB”)+未压缩大小+压缩大小+ zlib压缩字符串。

例如,在我的.vrscene中,我有这样的压缩列表:“ZIPB2C01000015000000e7X81OT0TG4S5ENN3D8Z8IVAPODONF7EA”

这意味着“e7X81OT0TG4S5ENN3D8Z8IVAPODONF7EA” - zlib压缩字符串。但我不知道如何解压缩它。当我做Base64解码时,我收到头0x7bb5。我不知道这样的标题。也许我不应该使用Base64而应该做其他事情呢?

2 个答案:

答案 0 :(得分:0)

文档说十六进制,但您提供的字符串包含其他字符。它可能不是base64,因为您在开始时没有获得有效的zlib标头。 (顺便说一句,当我使用base64解码它时,我得到0x7b 0xb5,而不是你得到的。但无论如何,它不是一个zlib头。)你有更好的描述来源吗?格式?

数据必须是高度可压缩的,例如全部为零,因为它显然从4140字节变为21字节。

答案 1 :(得分:0)

所以我知道这很旧,但是这里的信息足以让我找到解决方案,唯一的区别是我有一个来自不同vrscene文件的不同压缩列表。

建立后,您需要从字符串中删除前20个字符,因为它们只是vray使用的描述符,而不是压缩数据的一部分。

import base64, zlib

data = "ZIPCB81900003C000000eAHt0iERAAAMxLDC9694MkYCaqCXVZMHDDDAAAMMMMAAAwwwwAADDDDAAAMMMMAAAwwwwMC7gQMbojNx"
encoded_data = data[20:] #"eAHt0iERAAAMxLDC9694MkYCaqCXVZMHDDDAAAMMMMAAAwwwwAADDDDAAAMMMMAAAwwwwMC7gQMbojNx"
compressed_data = base64.b64decode(encoded_data)
hex_data = zlib.decompress(compressed_data)
# b'\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00\x08\x00\x00\x00...'

此时,您将获得原始十六进制列表,而无需任何压缩。如果要将其转换为可读的python数据类型,则可以使用struct来解压缩它们,具体取决于列表中存储的数据类型。

在链接的文档中的进一步阅读说明,所有此类列表每个条目存储为4个字节(在文档中写为8个半字节,但就python而言,它仅为4个字节)。有了这些信息,我们可以确定列表中的条目数应为hex_data / 4的长度,并构建一个结构格式字符串,该字符串将立即解压缩整个列表。

import struct

#I have a list of ints as my example, but for floats you could use "f" instead
format = "i" * int(len(hex_data)/4)
values = struct.unpack(format, hex_data)
# [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, ...]

还有“颜色”列表和“矢量”列表,但它们只是需要展平的浮动列表。

vectors = []
for i in range(0, int(len(values)), 3):
    vectors.append(tuple(values[i:i+3]))

由于这种方法似乎可以处理我到目前为止遇到的所有压缩十六进制列表,因此似乎您最初尝试从中解析数据的文件存在问题,或者开发人员曾经使用base64以外的编码方法,但此后一直采用base64编码(也许这就是“ ZIPC”出现在我的文件中而不是“ ZIPB”的原因)。