需要有关C中lzss压缩的帮助

时间:2017-04-16 14:47:37

标签: c compression

我使用了https://oku.edu.mie-u.ac.jp/~okumura/compression/lzss.c

中的代码

此代码用于文件压缩。我已经为给定的字符串修改了它。例如:

  

d(2306):AuthorisationScheme:RADIUSserveratfd04:BD3:80e8:1 :: 1usingPAPD / 6LoWPANd(2306):WritingModule:SecurityConfigD / 6LoWPANd(2306):WritingModule:RunCoordinatorD / 6LoWPANd(2306):RequestingmoduleaddressD / 6LoWPANd(2306) :WritingModule:GetAddressD /智能卡的JNI(2781):SmartCard_state_update_callback:状态= 6D / SmartCardNative(2781):状态= 6D /智能卡(2781):PN532Smartcard_loop_threadexitD /智能卡的JNI(2781):SmartCard_loop_thread:SMARTCARD_STATUS_ABORTD /智能卡(2781): Smartcard_loop_uninitD /智能卡(2781):2D / serialcomm_pn532(2781):PN532:Readingfrom的/ dev / ttyUSB0 - > d /智能卡(2781):接收段(0x3)fromPN532:(DATABUF [0]:为0x1)(0x1f5988)d /智能卡(2781):ReceivedStatusfromPN532:OK(CMD:0X2)d /智能卡的JNI(2781):SmartCard_listener_update_callbackD /智能卡(2781):接收(0x1c2)fromPN532:(DATABUF [0]:0x32)(0x1f5988)d /智能卡(2781):VD(2306):AuthorisationScheme:RADIUSserveratfd04:BD3:80e8:1 :: 1usingPAPD / 6LoWPANd(2306):

我面临的问题是,如果我想压缩包含此文件的文件,代码就能够做到这一点。但是我修改过的代码却没有什么问题。压缩文件的最后2位是不同的。虽然文件和缓冲区的内容完全相同。

原始代码正在从文件中读取。在这里,我提供了相同内容的字符串。

代码在这里:

/* LZSS encoder-decoder  (c) Haruhiko Okumura */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define EI 11  /* typically 10..13 */
#define EJ  4  /* typically 4..5 */
#define P   1  /* If match length <= P then output one character */
#define N (1 << EI)  /* buffer size */
#define F ((1 << EJ) + P)  /* lookahead buffer size */

int bit_buffer = 0, bit_mask = 128;
unsigned long codecount = 0, textcount = 0;
unsigned char buffer[N * 2];
FILE *infile, *outfile, *outfile2, *outfile3;

/*----*/
unsigned long payload_i = 0;
int tt = 0;
unsigned int buf_load[16000];
unsigned char *string_buf= "d(2306):AuthorisationScheme:RADIUSserveratfd04:bd3:80e8:1::1usingPAPD/6LoWPANd(2306):WritingModule:SecurityConfigD/6LoWPANd(2306):WritingModule:RunCoordinatorD/6LoWPANd(2306):RequestingmoduleaddressD/6LoWPANd(2306):WritingModule:GetAddressD/smartcard-jni(2781):SmartCard_state_update_callback:status=6D/SmartCardNative(2781):status=6D/smartcard(2781):PN532Smartcard_loop_threadexitD/smartcard-jni(2781):SmartCard_loop_thread:SMARTCARD_STATUS_ABORTD/smartcard(2781):Smartcard_loop_uninitD/smartcard(2781):2D/serialcomm_pn532(2781):PN532:Readingfrom/dev/ttyUSB0-->D/smartcard(2781):Received(0x3)fromPN532:(dataBuf[0]:0x1)(0x1f5988)D/smartcard(2781):ReceivedStatusfromPN532:OK(cmd:0x2)D/smartcard-jni(2781):SmartCard_listener_update_callbackD/smartcard(2781):Received(0x1c2)fromPN532:(dataBuf[0]:0x32)(0x1f5988)D/smartcard(2781):vd(2306):AuthorisationScheme:RADIUSserveratfd04:bd3:80e8:1::1usingPAPD/6LoWPANd(2306):";
/*----*/

void error(void)
{
    printf("Output error\n");  exit(1);
}

void putbit1(void)
{
    outfile2  = fopen("file2.lzss", "a");
    bit_buffer |= bit_mask;
    if ((bit_mask >>= 1) == 0) {
/*----*/
        buf_load[payload_i] = bit_buffer;
        if (fputc(buf_load[payload_i], outfile3) == EOF) error();
        payload_i++;
/*----*/

        if (fputc(bit_buffer, outfile2) == EOF) error();
        if (fputc(bit_buffer, outfile) == EOF) error();
        bit_buffer = 0;  bit_mask = 128;  codecount++;
    }
    fclose(outfile2);
}

void putbit0(void)
{
    outfile2  = fopen("file2.lzss", "a");
    if ((bit_mask >>= 1) == 0) {
/*----*/
        buf_load[payload_i] = bit_buffer;
        if (fputc(buf_load[payload_i], outfile3) == EOF) error();
        payload_i++;
/*----*/
        if (fputc(bit_buffer, outfile2) == EOF) error();
        if (fputc(bit_buffer, outfile) == EOF) error();
        bit_buffer = 0;  bit_mask = 128;  codecount++;
    }
    fclose(outfile2);
}

void flush_bit_buffer(void)
{
    outfile2  = fopen("file2.lzss", "a");
    if (bit_mask != 128) {
        if (fputc(buf_load[payload_i], outfile3) == EOF) error();
        if (fputc(bit_buffer, outfile2) == EOF) error();
        if (fputc(bit_buffer, outfile) == EOF) error();
        codecount++;
    }
    fclose(outfile2);
}

void output1(int c)
{
    int mask;

    putbit1();
    mask = 256;
    while (mask >>= 1) {
        if (c & mask) putbit1();
        else putbit0();
    }
}

void output2(int x, int y)
{
    int mask;

    putbit0();
    mask = N;
    while (mask >>= 1) {
        if (x & mask) putbit1();
        else putbit0();
    }
    mask = (1 << EJ);
    while (mask >>= 1) {
        if (y & mask) putbit1();
        else putbit0();
    }
}

void encode(void)
{
    int i, j, f1, x, y, r, s, bufferend, c;

    for (i = 0; i < N - F; i++) buffer[i] = ' ';
    for (i = N - F; i < N * 2; i++) {
        if ((c = fgetc(infile)) == EOF) break;
        if((c = string_buf[tt++]) == '\0') break;
        buffer[i] = c;  textcount++; //tt++;
    }
    bufferend = i;  r = N - F;  s = 0;
    while (r < bufferend) {
        f1 = (F <= bufferend - r) ? F : bufferend - r;
        x = 0;  y = 1;  c = buffer[r];
        for (i = r - 1; i >= s; i--)
            if (buffer[i] == c) {
                for (j = 1; j < f1; j++)
                    if (buffer[i + j] != buffer[r + j]) break;
                if (j > y) {
                    x = i;  y = j;
                }
            }
        if (y <= P) output1(c);
        else output2(x & (N - 1), y - 2);
        r += y;  s += y;
        if (r >= N * 2 - F) {
            for (i = 0; i < N; i++) buffer[i] = buffer[i + N];
            bufferend -= N;  r -= N;  s -= N;
            while (bufferend < N * 2) {
                if ((c = fgetc(infile)) == EOF) break;
                if((c = string_buf[tt++]) == '\0') break;
                //tt++;
                buffer[bufferend++] = c;  textcount++;
            }
        }
    }
    flush_bit_buffer();
    printf("text:  %ld bytes\n", textcount);
    printf("code:  %ld bytes (%ld%%)\n",
        codecount, (codecount * 100) / textcount);
}

int getbit(int n) /* get n bits */
{
    int i, x;
    static int buf, mask = 0;

    x = 0;
    for (i = 0; i < n; i++) {
        if (mask == 0) {
            if ((buf = fgetc(infile)) == EOF) return EOF;
            mask = 128;
        }
        x <<= 1;
        if (buf & mask) x++;
        mask >>= 1;
    }
    return x;
}

void decode(void)
{
    int i, j, k, r, c;

    for (i = 0; i < N - F; i++) buffer[i] = ' ';
    r = N - F;
    while ((c = getbit(1)) != EOF) {
        if (c) {
            if ((c = getbit(8)) == EOF) break;
            fputc(c, outfile);
            buffer[r++] = c;  r &= (N - 1);
        } else {
            if ((i = getbit(EI)) == EOF) break;
            if ((j = getbit(EJ)) == EOF) break;
            for (k = 0; k <= j + 1; k++) {
                c = buffer[(i + k) & (N - 1)];
                fputc(c, outfile);
                buffer[r++] = c;  r &= (N - 1);
            }
        }
    }
}

int main(int argc, char *argv[])
{
    int enc;
    char *s;
    memset(buf_load, '\0', sizeof(buf_load));
    outfile3 = fopen ("file1.lzss", "wb");

    if (argc != 4) {
        printf("Usage: lzss e/d infile outfile\n\te = encode\td = decode\n");
        return 1;
    }
    s = argv[1];
    if (s[1] == 0 && (*s == 'd' || *s == 'D' || *s == 'e' || *s == 'E'))
        enc = (*s == 'e' || *s == 'E');
    else {
        printf("? %s\n", s);  return 1;
    }
    if ((infile  = fopen(argv[2], "rb")) == NULL) {
        printf("? %s\n", argv[2]);  return 1;
    }
    if ((outfile = fopen(argv[3], "wb")) == NULL) {
        printf("? %s\n", argv[3]);  return 1;
    }
    if (enc) encode();  else decode();
    fclose(infile);  fclose(outfile);
    fclose(outfile3);
    return 0;
}

看起来问题在于缓冲区读写与文件读写。在文件读写中,指针增加到下一个mem loc并以相同的方式读写。在字符串中,通过递增索引读取每个数组,然后将压缩值写入文件写入文件中。在文件中,它被读作二进制(wb),在字符串中它被读作数组元素。可能有问题吗?需要专家的建议。

1 个答案:

答案 0 :(得分:0)

void flush_bit_buffer(void)
{
    outfile2  = fopen("file2.lzss", "a");
    if (bit_mask != 128) {
        flush_bit[payload_i] = bit_buffer; /*This last bit should be put which I missed. It solved my issue*/
        if (fputc(buf_load[payload_i], outfile3) == EOF) error();
        if (fputc(bit_buffer, outfile2) == EOF) error();
        if (fputc(bit_buffer, outfile) == EOF) error();
        codecount++;
    }
    fclose(outfile2);
}

我通过在代码段中添加该行来解决它。我需要添加最后一位缓冲区来解决这个问题。