lzss解码EOF字符问题

时间:2017-05-14 05:11:00

标签: c string

我正在使用Okamura的lzss:https://oku.edu.mie-u.ac.jp/~okumura/compression/lzss.c

的实现
int enc_i = 0;


int getbit(int n, unsigned char *enco_buf) /* 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;
            //if ((buf = fgetc(infile)) == EOF) return EOF;
            if((buf = enco_buf[enc_i]) == '\0') break;
            //buf = enco_buf[enc_i];
            enc_i++;
            //printf("\nValue of enc : %d\n", enc_i);
            mask = 128;
        }
        x <<= 1;
        if (buf & mask) x++;
        mask >>= 1;

    }
    return x;
}

void decode(unsigned char *enco_buf)
{
    int i, j, k, r, c;
    outfile = fopen ("test_lib.txt", "wb");

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

我没有从文件中获取输入,而是采用一个编码缓冲区,我将其传递给函数decode(),后者依次传递给getbit()。但它正在解码到一定数量的比特,即。 43.我猜的是我把'\ 0'而不是EOF(因为它在文件结束标记中)来检测字符串结束。这可能是执行break语句执行'\ 0'的问题。这可能不是真的,但情况可能如此。编码部分没有问题,因为我用原始代码验证了它。任何人都可以建议问题出在哪里?

编辑:源代码:

/* LZSS encoder-decoder (Haruhiko Okumura; public domain) */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "lzss_lib.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) + 1)  /* lookahead buffer size */

int bit_buffer = 0, bit_mask = 128;
unsigned long codecount = 0, textcount = 0;
unsigned char buffer[N * 2];
int payload_i = 0;
int enc_i = 0;

FILE *infile, *outfile;

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

void putbit1(unsigned char *put_buf0)
{
    bit_buffer |= bit_mask;
    if ((bit_mask >>= 1) == 0) {
        put_buf0[payload_i] = bit_buffer;
        payload_i++;
        bit_buffer = 0;  bit_mask = 128;  codecount++;
    }
}

void putbit0(unsigned char *put_buf1)
{
    if ((bit_mask >>= 1) == 0) {
        put_buf1[payload_i] = bit_buffer;
        payload_i++;
        bit_buffer = 0;  bit_mask = 128;  codecount++;
    }
}

void flush_bit_buffer(unsigned char *flush_bit)
{
    if (bit_mask != 128) {
        flush_bit[payload_i] = bit_buffer;
        codecount++;
    }
}

void output1(int c, unsigned char *buf_output1)
{
    int mask;

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

void output2(int x, int y, unsigned char *buf_output2)
{
    int mask;

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

void encode(unsigned char *string_buf, unsigned char *out_buf, unsigned long *out_buf_len)
{

    int i, j, f1, x, y, r, s, bufferend, c, tt;
    tt = 0;
    for (i = 0; i < N - F; i++) buffer[i] = ' ';
    for (i = N - F; i < N * 2; i++) {
        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) {  y = 1;  output1(c, out_buf);  }
        else output2(x & (N - 1), y - 2, out_buf);

        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 = string_buf[tt]) == '\0') break;
                buffer[bufferend++] = c;  textcount++; tt++;
            }

        }

    }

    flush_bit_buffer(out_buf);
    *out_buf_len = codecount;
    printf("text:  %ld bytes\n", textcount);
    printf("code:  %ld bytes (%ld%%)\n", codecount, (codecount * 100) / textcount);

}

int getbit(int n, unsigned char *enco_buf) /* 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;
            //if ((buf = fgetc(infile)) == EOF) return EOF;
            if((buf = enco_buf[enc_i]) == '\0') break;
            //buf = enco_buf[enc_i];
            enc_i++;
            printf("\nValue of enc : %d\n", enc_i);
            mask = 128;
        }
        x <<= 1;
        if (buf & mask) x++;
        mask >>= 1;

    }

    return x;
}

void decode(unsigned char *enco_buf)
{
    int i, j, k, r, c;
    outfile = fopen ("test_lib.txt", "wb");

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

和测试示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "lzss_lib.h"

unsigned char compr_data[4096];
unsigned long pw = 0;
unsigned long payload_len = 0;
volatile int errno;
unsigned char *unc_data = "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):";
FILE *outfile;

int main(void) {
    memset (compr_data, '\0', sizeof(compr_data));
    encode(unc_data, compr_data, &payload_len);

    decode(compr_data);

    return 0;
}

0 个答案:

没有答案