在Python中正确实现ArchiveLib压缩

2024-10-02 08:19:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写了一个刺绣输入和输出python模块EmbroidePy/pyembroidery,HUS和VIP是两种相关的、旧的和流行的刺绣格式,它们使用一种特定的失效压缩格式,特别是ArchiveLib, AL_GREENLEAF_LEVEL_4。许多刺绣软件套件使用旧的.dll文件al21mfc.dll来利用正确的压缩。包含一个.dll文件是不可能的,但是似乎没有任何合理的方法来无缝地模拟一个失效的压缩格式

有一个可接受的C++绣读写库,由绣花模团队实际实现了这个,emb-compress,我也想这样做。

我希望能够在python或者Java中压缩和解压这些元素。我更喜欢可读的代码,但这远不是一个要求

但是,有问题

    <> > > {CD3>}中的C++代码显然是反编译的,看起来像是胡言乱语,只不过是把源代码移植过了,难以处理。p>
  • ArchiveLib源代码与产品本身一起发布,但无法定位。有了它,就可以理解特定的需求,并在python中实现它

解决方案不需要很漂亮。解决方案不需要很快。我已经考虑过把C++代码编译成Python中实现虚拟CPU的某种字节码。或者用另一个程序移植看起来乱七八糟的代码,这样会增加乱七八糟的程度,或者手工操作(但我总是很快就迷失了方向)。我在网络最黑暗的角落里寻找原始的源代码。我的成绩很差

似乎应该有足够的资源让某些东西发挥作用,但每个想法似乎都比下一个更难,更不实用。有什么我遗漏的或一些想法,可以迅速使这些解决方案之一的工作?或者其他可行的解决方案


Tags: 模块文件代码源代码格式解决方案dllal
1条回答
网友
1楼 · 发布于 2024-10-02 08:19:01

ArchiveLib compression是执行ARJ压缩的Robert Jung的分许可产品。ARJ和ArchiveLib也采用了相同的方案,专利保护已经过期

它发送压缩的哈夫曼表,通过读取n个哈夫曼编码长度来构建这些表。这些都是检查他们是否解决了平衡哈夫曼树。它们从最长的码字到最短的码字排序,并列的条目到最小的值

如果这些值的长度是4,8,2,2,它就给出了8,4,2,2的码字0,10,110,111,它们的顺序反映了它们的位置。所以第一个条目是10,第二个是0,第三个是110,第四个是111

块被16个字节读取以传送符号的数量。后面是字符长度表,这是哈夫曼编码的。然后使用字符长度表来构建字符表。使用哈夫曼表构建字符哈夫曼表。然后发送第三个距离表,该表给出了窗口中的回望值,以便读取


字符长度表

5位计数数据。这可以传递0到32个条目的值。如果为零,则读取另一个5位值,该值用于所有值

对于计数中的每个值,我们读取一个可变长度。对于索引3处的特殊值(给定第4个值),前缀为2位,在索引中向前跳0到3个值。这些跳过的值被视为计数的一部分。前三项是字符表中的特殊命令代码

这将提供多达32个不同的值长度的哈夫曼代码长度可以


字符表

9位计数。这意味着它可以提供从0到511的值。如果是0,那么所有值都是紧跟其后的9位

条目数是实际填充表的值。如果是4,那么在511条目表中有4个不同的非零条目

编码的数据是如何跳过或填充提供的相关数据。0表示我们在表序列中设置了一个0。1意味着我们读取4位,然后将3加到该值上,然后将许多表项归零。2意味着我们读取9位,然后将20加到该值上,然后将许多表项归零。对于任何大于该值的值,我们减去2,然后简单地将其放入表中

结果是一个列表,列出了最多511个元素所需的所有代码的长度(任何没有得到值的条目都是0)。然后将其发送到huffman表生成算法,以检查其有效性并生成表。这将为0到511之间的令牌分配哈夫曼码


距离哈夫曼

5位计数。如果为零,则为所有值提供后续5位数

每个条目读取一个可变长度的数据值。这将产生0-32个长度值。然后用它们构建一个相关的huffman表

这个表将由一个huffman表定义多达32个不同的整数值


可变长度数据

3位值。如果不是7,则返回该值。 如果7,则读取0到13个额外字节,直到找到非一个值。因此,如果值小于7,则使用该值。如果大于7,则每增加一个1表示一个大于1的值。所以11110是8,111110是9,最多13位。这将给出0到20之间的值。在3到16位之间


减压

实际的解压意味着读取块和表。然后使用字符表和距离表(如果需要)压缩流。根据字符表检查每个值以提供标记。如果值为0-255,则为文字。如果值为510,则表示结束命令。如果该值大于255,则对应于返回窗口的指针。大于255的值对应于str(v-253)字符的压缩。也就是说256意味着我们从窗口读取3个字符。257表示4个字符。高达509意味着我们从窗口读取255个字符。如果我们从一个查找中读取一个值,那么流上的下一个值就是使用distance Huffman表向后读取的距离


压缩

任何适合解压方案的压缩方案都可以工作。它是如何找到编码的东西是很少关心的。ARJ的专利只是简单地描述了如何快速压缩东西,这并不是什么大问题。然而,一个有趣的方法是根本不压缩东西,而只是通过头强制一个空操作

编写空操作压缩的示例

块大小的16位。如果我们需要超过32k个元素,我们就必须再写一个块

  • 写字符长度哈夫曼。 5字节:00000,我们有0个条目。1长度。他们都是8岁。 5字节:01010,所有值均为10,表示长度为8

字符长度哈夫曼只返回10

  • 写人物哈夫曼。 9位:100000000,256个条目

所有条目都将查询字符长度huffman并得到值10,即8

字符Huffman表将有256个8位条目。这将构建一个文本表,其中每个字节都完全等于自身。因为有256个绑定条目,所以它们首先在最低的元素中获取

距离哈夫曼(我们从不使用这个)。 5位:00000无输入。 5位:00000任何值都不重要

这使得编写文本表需要29位。然而,为了使这个方法非常有用,我们希望它精确地除以8位。我们可以通过改变哈夫曼距离来做到这一点,因为所有的值都是文本,所以我们从不使用哈夫曼距离

5位:00001 1距离哈夫曼。 3位:111我们有一个可变长度值7或更多。 5位:11110我们在7的基础上加上4,长度为11。但实际上我们是在填充

(10)+(9)+(5+3+5)=32位

0B000000101000000001111110 可存储为单个整数:0x02A001FE

所以对于compress,我们可以简单地给出块的大小,然后0x02A001FE和未压缩的数据。它会被认为是压缩的。因为我实际上不能推荐使用一个基本上死的压缩方案

相关问题 更多 >

    热门问题