【问题标题】:How LZMA decompression algorithm works?LZMA 解压算法是如何工作的?
【发布时间】:2020-12-18 04:16:02
【问题描述】:

我一直不明白 lzma 解压缩算法是如何工作的,更准确地说是这个函数

int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, 
        const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);

它处于无限循环中,具有相同大小的 SizeT *destLen 和 SizeT *srcLen 的固定大小,逻辑上 destLen(未压缩数据)应大于 srcLen(压缩数据)并具有预定义的比率,我没有'不知道它是如何在相同大小的情况下工作的,或者它可以接受任何大小,然后它有一个临时缓冲区,它将存储数据然后用它的方法处理它们。

【问题讨论】:

    标签: c embedded lzma


    【解决方案1】:

    这个功能确实不好用。它是为增量解压缩而构建的。因此,设想的用例是这样的:

    • 程序从文件等源读取压缩数据。数据以块的形式读取,例如一次 1000 个字节。
    • 每个块都被解压缩到一个缓冲区中。缓冲区通常更大,例如2000 字节。解压缩块后,目标缓冲区将部分填充数据,例如1738 字节。
    • 对于每个块,将进一步处理解压缩的数据,例如写入文件。

    解压文件并将结果写入另一个文件的简化代码如下所示:

    
    file_in = open_file(...);
    file_out = open_file(...);
    while (!eof(file_in)) {
       len_in = read(file_in, buf_in, 1000);
       len_out = decompress(buf_in,len_in, buf_out, 2000);
       write(file_out, buf_out, len_out);
    }
    close(file_in);
    close(file_out);
    

    所以LzmaDec_DecodeToBuf的相关参数为:

    • dest: 指向目标缓冲区的指针
    • destLen:指向目标长度的指针。调用者将长度设置为分配的缓冲区大小。 LzmaDec_DecodeToBuf 更新长度以包含解压缩数据的长度。
    • src: 指向源缓冲区的指针
    • srcLen:指向源长度的指针。调用者将长度设置为缓冲区中压缩数据的长度。 LzmaDec_DecodeToBuf 更新长度以包含已处理的字节数。

    srLen 可能很棘手。在大多数情况下,将处理传递给函数的所有数据。但如果解压后的数据不适合目标缓冲区,它只会处理部分数据。因此,需要将解压缩的数据写入文件以释放目标缓冲区,并且需要使用剩余数据再次调用该函数。这已从简化代码中省略。

    另外一个遗漏是最终确定。在输入文件的末尾,LzmaDec_DecodeToBuf 可能需要使用不同的完成模式最后一次调用。

    【讨论】:

    • 感谢@Codo 的精彩解释,再问一个问题,LZMA 是否允许流式解密?
    • 您的意思是“加密/解密”如“使用密钥”/“通信安全”吗?还是您的意思是“压缩”/“解压”?而且我不确定您所说的“流媒体”是什么意思。你能说得更具体点吗?
    • 我的意思是压缩/解压上下文,用流解压意味着我可以在循环块中解压缩,即解压(bloc2)不依赖于解压(bloc1)的结果,使用RLE时就是这种情况但不确定 LZMA
    • 我仍然不确定您的意思:在我的回答中,使用了循环和块(类似于您的“块”?)。但是一个块的压缩取决于前一个块。只要把它想象成减压引擎的状态。它保存在CLzmaDec 结构中,需要传递给每个调用。也可以单独压缩每个块,但解压缩率会大大降低。但是我不明白你为什么提到循环。
    • 忘记循环@Codo,非常感谢。还有一个歧义,我可以在每次迭代中控制 destLen 吗(即迭代 1:我需要一个 32 字节的缓冲区,迭代 2 128 字节......)如果是,在这种情况下是否有任何规则来设置 srcLen 大小?还提到 LzmaDec_DecodeToBuf 更新长度以包含解压缩数据的长度,这意味着参数 destLen 定义了 dest 缓冲区的最大大小,但 LzmaDec_DecodeToBuf 可以将其更新为小于 destLen 的值,对吗?
    猜你喜欢
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    相关资源
    最近更新 更多