绿叶档案馆?

发布于 2024-12-11 06:27:55 字数 239 浏览 0 评论 0原文

我们的产品使用 Greenleaf Archive Library,这是一个旧的 Windows 压缩库。我们现在希望迁移到 Mac,但我很确定我们从 Greenleaf 获得的 .lib 文件无法在该平台上运行。

除了切换到另一个压缩库(这会因多种原因而出现问题)之外,有谁知道任何替代方案,例如该库的开源版本或 Mac 端口?

Our products use the Greenleaf Archive Library, an old compression library for Windows. We're now looking to move to the mac, but I'm pretty sure the .lib files we got from Greenleaf won't work on that platform.

Other than just switching to another compression library, which would be problematic for several reasons, does anyone know of any alternatives, like an open source version of the library or a mac port?

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

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

发布评论

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

评论(2

鹿港巷口少年归 2024-12-18 06:27:55

我们这里提供的 ArchiveLib 2.12 版本附带了完整的源代码,并且可以在各种编译器下轻松构建。
检查您的原始安装包,看看它是否有安装源的选项。


编辑(很久以后):正如我在评论中提到的,源代码中缺少一个方法。由于我放在那里的链接似乎已经消失,我添加了下面的代码。

//
// void ALStorage::YieldTime()
//
// ARGUMENTS:
//
//  None.
//
// RETURNS
//
//  Nothing.
//
// DESCRIPTION
//
//  This function has two important things to do.  It gets called
//  at a few different points in the process of reading or writing data
//  from storage objects.  During normal reading and writing, it
//  will get called every time the buffer is loaded or flushed.
//
//  If we are in Windows mode, we execute a PeekMessage() loop.  This
//  makes sure that we aren't hogging the CPU.  By doing it this way,
//  the programmer can be ensure that he/she is being a good citizen
//  without any significant effort.
//
//  The second important function is that of calling the monitor function.
//  The user interface elements need to be updated regularly, and this
//  is done via this call.
//
// REVISION HISTORY
//
//   May 26, 1994  1.0A  : First release
//

void AL_PROTO ALStorage::YieldTime()
{
    if ( mpMonitor )
        mpMonitor->Progress( Tell(), *this );
    /*
     * For right now I am going to put the PeekMessage loop in the load
     * buffer routine by default.  Most Windows applications are going
     * to want to use this, right?
     */
#if defined( AL_WINDOWS_GUI )
    MSG msg;

    while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
        TranslateMessage( &msg );
        DispatchMessage(&msg);
    }
#endif
}

The 2.12 version of ArchiveLib we've got here shipped with full source code and builds fairly painlessly under various compilers.
Check your original install package and see if it has an option to install the source.


Edit (much later): As I mentioned in the comments, there was one missing method in the source code. As the link I put there seems to have vanished, I've added the code below.

//
// void ALStorage::YieldTime()
//
// ARGUMENTS:
//
//  None.
//
// RETURNS
//
//  Nothing.
//
// DESCRIPTION
//
//  This function has two important things to do.  It gets called
//  at a few different points in the process of reading or writing data
//  from storage objects.  During normal reading and writing, it
//  will get called every time the buffer is loaded or flushed.
//
//  If we are in Windows mode, we execute a PeekMessage() loop.  This
//  makes sure that we aren't hogging the CPU.  By doing it this way,
//  the programmer can be ensure that he/she is being a good citizen
//  without any significant effort.
//
//  The second important function is that of calling the monitor function.
//  The user interface elements need to be updated regularly, and this
//  is done via this call.
//
// REVISION HISTORY
//
//   May 26, 1994  1.0A  : First release
//

void AL_PROTO ALStorage::YieldTime()
{
    if ( mpMonitor )
        mpMonitor->Progress( Tell(), *this );
    /*
     * For right now I am going to put the PeekMessage loop in the load
     * buffer routine by default.  Most Windows applications are going
     * to want to use this, right?
     */
#if defined( AL_WINDOWS_GUI )
    MSG msg;

    while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
        TranslateMessage( &msg );
        DispatchMessage(&msg);
    }
#endif
}
烟酉 2024-12-18 06:27:55

Greenleaf Archive Lib 有一些源代码,它们被混淆成各种函数。如今,借助现代 IDE,您可以通过重构来很好地解决这个问题。我还与使用它的 Mark Nelson 进行了交谈,他通知说他们已经从编写 ARJ 的 Robert Jung 那里获得了代码的再许可(存档 Robert Jung),从那时起 ARJ 源代码已经可用,尽管我发现没有可接受的许可证,但我可以确认存档是相同的。除了 Greenleaf 的滑动窗口较小之外。

Compression Parameters
The HUS/VIP compression does seem to use the ARJ decode (1 to 3) with a dictionary size of 1024 instead of 26k.

Parameter   Value
CODE_BIT    16
THRESHOLD   3
MAXMATCH    256
DICBIT  10
DICSIZE 1024
NT  19
TBIT    5
NP  15
PTABLESIZE  256
PBIT    5
NC  511
CTABLESIZE  4096
CBIT    9
NPT 19

https://community.kde.org/Projects/Liberty/File_Formats/Husqvarna_HUS

现在,ARJ 中的参数 DICSIZE 为 22k,而不是 1k。但是,ARJ 中的 NC 值也是 510,而不是 Greenleaf 中的 511。解码压缩参数会更改字典大小。也就是说,每级额外压缩都会增加 2 的幂。它实际上是通过位移位来设置大小。

我没有看到任何经过适当许可的东西,因此您可能必须从头开始重写 arj 压缩方案。尽管技术细节很少,而且源代码本身也很奇怪。显然,他在奇怪的部分获得了一项现已过期的专利,他显然正在做一些哈希表,通过在内存中构建一些表元素并使用它们来索引查找下一个索引来进行霍夫曼编码。它似乎是一个使用可选提供字典的 LZSS 方案。但是,该算法的实际工作原理非常类似于 zip 的 deflate 方案,它实际上可能适合 deflate。因此,如果由于某种原因无法编译一些您可能没有的混淆源代码,您可以重写它。


我从头开始重写了解压,MIT授权代码:

https:// github.com/EmbroidePy/pyembroidery/blob/master/pyembroidery/Embcompress.py

这也适用于 ARJ 压缩,因为我不关心窗口 尺寸。它会读取任何大小的窗口,因为它只会读取文件中的数据。

对于压缩,我不想做大量编写真实方案的跑腿工作,所以我开发了一种特殊的作弊方法。我们编写了一个包含 256 个 8 位长条目的假表。它们本身将在平局中编号最低,因此它们将精确映射为等于角色本身。

Block writing.

16 bits filesize

- Writing Character_Length huffman.
5 bytes: 00000, we have 0 entries. 1 length. They are all 8.
5 bytes: 01010, all values are 10, meaning length 8.
---- CharLength huffman only returns 10.

- Writing Character Huffman.
9 bits: 100000000, 256 entries.
---- All character build with c_len value 10, which is 8. No bits are read.
---- Huffman table of 256 8 entries.

Distance Huffman. (we are never using this).
5 bits: 00000 No entries.
5 bit: 00000 Any value doesn't matter. Since we're never using it.

然而!

45 % 8 = 5
16 + 10 + 9 + 10 = 45 bits.
And we'd have to offset all of our bytes by 3 bits.

So we need a huffman table bit length that is exactly mod 8.
    5 bit: 00001 1 distance huffman.
    3 bit: 111 we have a variable length value 7 or more.
    5 bit: 11110 we add 4 to this 7 for 11. Because really we want to pad bits.

(16) + (10) + (9) + (5 + 3 + 5) = 48 bits. 6 bytes.
2 bytes filesize. Followed by 4 bytes:
0b00000010101000000000000111111110

这可以存储在单个整数中:
0x02A001FE


因此要执行Greenleaf或ARJ压缩。

2-byte-block-size + 0x02A001FE + uncompressed_stream

如果您需要超过 2^16 字节,则需要更多块。你用同样的方法做它们。

Greenleaf Archive Lib has some source code that exists which is obfuscated into various functions. Today with modern IDEs you can do a pretty good job fixing this by refactoring things. I also spoke with Mark Nelson who worked with it and he notified that they had sublicensed the code from Robert Jung who wrote ARJ (Archive Robert Jung), since that time ARJ source code has been made available though I find no acceptable license for it, but I can confirm the archiving is the same. Except that Greenleaf has a smaller sliding window.

Compression Parameters
The HUS/VIP compression does seem to use the ARJ decode (1 to 3) with a dictionary size of 1024 instead of 26k.

Parameter   Value
CODE_BIT    16
THRESHOLD   3
MAXMATCH    256
DICBIT  10
DICSIZE 1024
NT  19
TBIT    5
NP  15
PTABLESIZE  256
PBIT    5
NC  511
CTABLESIZE  4096
CBIT    9
NPT 19

https://community.kde.org/Projects/Liberty/File_Formats/Husqvarna_HUS

Now, the parameter DICSIZE in ARJ is 22k rather than 1k. But, also the value NC is 510 in ARJ rather than 511 as it is with Greenleaf. The decode compression parameter changes the dictionary size. Namely each level of extra compression goes up by a power of 2. It's actually setting the size by a bit shift.

I don't see any properly licensed stuff so you may have to rewrite the arj compression scheme from scratch. Although technical details are sparse, and the source code itself is weird. Apparently he got a now expired patent on the weird part where he's apparently doing some hash tables to do the Huffman encoding by building some tables elements in memory and using them to index find the next index. It appears to be an LZSS scheme using an optional providing of a dictionary. But, the actual workings of the algorithm is very much like like with zip's deflate scheme, it might actually be spot on for deflate. So if compiling some obfuscated source code you might not have isn't possible for some reason you can rewrite it.


I rewrote the decompression from scratch, and MIT licensed code:

https://github.com/EmbroidePy/pyembroidery/blob/master/pyembroidery/EmbCompress.py

This will also work for ARJ compression since I didn't care about the window size. It'll read any size window since it will just read the data in the file.

For the compression I don't want to do the massive legwork of writing a real scheme so I've developed a special way to cheat. We write a fake table of 256 8 bit long entries. They will natively number lowest first in a tie so they will exactly map to be equal to the character themselves.

Block writing.

16 bits filesize

- Writing Character_Length huffman.
5 bytes: 00000, we have 0 entries. 1 length. They are all 8.
5 bytes: 01010, all values are 10, meaning length 8.
---- CharLength huffman only returns 10.

- Writing Character Huffman.
9 bits: 100000000, 256 entries.
---- All character build with c_len value 10, which is 8. No bits are read.
---- Huffman table of 256 8 entries.

Distance Huffman. (we are never using this).
5 bits: 00000 No entries.
5 bit: 00000 Any value doesn't matter. Since we're never using it.

However!

45 % 8 = 5
16 + 10 + 9 + 10 = 45 bits.
And we'd have to offset all of our bytes by 3 bits.

So we need a huffman table bit length that is exactly mod 8.
    5 bit: 00001 1 distance huffman.
    3 bit: 111 we have a variable length value 7 or more.
    5 bit: 11110 we add 4 to this 7 for 11. Because really we want to pad bits.

(16) + (10) + (9) + (5 + 3 + 5) = 48 bits. 6 bytes.
2 bytes filesize. Followed by 4 bytes:
0b00000010101000000000000111111110

This is storable in a single integer:
0x02A001FE


So to perform Greenleaf or ARJ compression.

2-byte-block-size + 0x02A001FE + uncompressed_stream

If you need more than 2^16 bytes, you'll need more blocks. You make them the same way.

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