首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >palmdoc的LZ77压缩

palmdoc的LZ77压缩
EN

Stack Overflow用户
提问于 2013-05-19 16:53:35
回答 1查看 650关注 0票数 2

我正在尝试创建一个实用程序来生成palmdoc/mobipocket格式的电子书文件,据说LZ77使用LZ77压缩技术来压缩他们的记录,但我发现与标准mobi有相当大的偏差,我的主要参考来源是Calibre电子书创建器with C implementation for palmdoc

在这个文件中,解压效果很好,但我无法使用其他实现或这个(Calibre代码不解压缩相同的)压缩相同的mobi记录。

我发现了一些不同之处,比如(<--我的注释跟在代码后面)

代码语言:javascript
复制
static Py_ssize_t <-- can replaced with size_t
cpalmdoc_do_compress(buffer *b, char *output) {
    Py_ssize_t i = 0, j, chunk_len, dist;
    unsigned int compound;
    Byte c, n;
    bool found;
    char *head;
    buffer temp; 
    head = output;
    temp.data = (Byte *)PyMem_Malloc(sizeof(Byte)*8); temp.len = 0;
    if (temp.data == NULL) return 0;
    while (i < b->len) {
        c = b->data[i];
        //do repeats
        if ( i > 10 && (b->len - i) > 10) { <-- ignores any match outside this range
            found = false;
            for (chunk_len = 10; chunk_len > 2; chunk_len--) {
                j = cpalmdoc_rfind(b->data, i, chunk_len);
                dist = i - j;
                if (j < i && dist <= 2047) { <-- 2048 window size instead of 4096
                    found = true;
                    compound = (unsigned int)((dist << 3) + chunk_len-3);
                    *(output++) = CHAR(0x80 + (compound >> 8 ));
                    *(output++) = CHAR(compound & 0xFF);
                    i += chunk_len;
                    break;
                }
            }
            if (found) continue;
        }

        //write single character
        i++;
        if (c == 32 && i < b->len) { <-- if space is encountered skip char & check for next sequence for match otherwise do this, due to this code had wrong result.
            n = b->data[i];
            if ( n >= 0x40 && n <= 0x7F) {
                *(output++) = CHAR(n^0x80); i++; continue;
            }
        }
        if (c == 0 || (c > 8 && c < 0x80))
            *(output++) = CHAR(c);
        else { // Write binary data <-- why binary data? LZ is for text encoding
            j = i;
            temp.data[0] = c; temp.len = 1;
            while (j < b->len && temp.len < 8) {
                c = b->data[j];
                if (c == 0 || (c > 8 && c < 0x80)) break;
                temp.data[temp.len++] = c; j++;
            }
            i += temp.len - 1;
            *(output++) = (char)temp.len;
            for (j=0; j < temp.len; j++) *(output++) = (char)temp.data[j];
        }
    }
    PyMem_Free(temp.data);
    return output - head;
}

这个实现正确吗?

EN

回答 1

Stack Overflow用户

发布于 2013-08-25 16:17:19

PalmDoc compression本质上是字节对压缩,即LZ77的变体

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16632931

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档