2

我一直在寻找一种压缩方法,使用 zlib 库(和函数compress)一个包含浮点变量的结构。

我看到的每个示例都展示了如何压缩字符串,特别是unsigned char*.

我的结构很简单:

struct Particle{
    float x;
    float y;
    float z;
};

我正在调用压缩函数,如下所示:

uLong initSize = sizeof(Particle);
uLongf destSize = initSize * 1.1 + 12;
Bytef *dataOriginal = (Bytef*)malloc( initSize );
Bytef *dataCompressed = (Bytef*)malloc( destSize );

Particle p;
memset( &p, 0, sizeof(Particle) );

p.x = 10.24;
p.y = 23.5;
p.z = 7.4;

memcpy( dataOriginal, &p, sizeof(p) );
compress( dataCompressed, &destSize, dataOriginal, initSize );

但是当我尝试解压缩我的数据以查看里面的内容时,我无法回到我的初始浮点值:

Bytef *decomp = (Bytef*)malloc( initSize );
uncompress( decomp, &initSize, dataCompressed, destSize );

for( int i = 0 ; i < initSize ; i++ ){
    std::cout << (float)decomp[i] << std::endl;
}

如果有人有这个问题的解决方案,我现在已经两天了......

4

1 回答 1

4

您需要将解压缩的数据复制回 Particle 结构,就像您首先将其复制出来一样。(或者你可以只使用演员而不是副本)。然后您将恢复结构中的原始浮点数。不管你认为你用'decomp[i]`做什么都没有任何意义。

然而,这有几个问题。首先,这只能保证在同一台机器上使用相同的编译器,甚至只能在相同版本的编译器中工作。如果不同的编译器或不同的版本选择以不同的方式对齐结构,则压缩数据将无法在两者之间传输。如果不同机器之间的浮点数表示不同,则压缩数据将不可传输。

此外,压缩三个浮点数时不会得到任何压缩。我认为这只是压缩大量此类 Particle 结构的前奏。那么也许你会得到这个。

最好先将浮点数转换为整数所需的精度。您应该知道应用程序的范围和有用的位数。这将在使用 之前进行压缩compress(),仅使用所需的位数,而不是每个浮点数 32。然后使用移位操作将这些整数可移植地转换为一系列字节。然后,您还可以将差分应用于连续粒子(例如 x1-x2、y1-y2、z1-z2),如果连续粒子之间存在相关性,这可能会改善压缩。

顺便说一句,* 1.1 + 12您应该使用代替compressBound(),它以 zlib 库为未来版本保证的方式完全满足您的需求。

于 2012-11-25T14:59:31.450 回答