2017-04-16 115 views
0

我用了從https://oku.edu.mie-u.ac.jp/~okumura/compression/lzss.c需要幫助就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:BD 3: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; 
} 

貌似問題在於緩衝讀寫VS文件讀寫。在文件讀寫中,指針增加到下一個mem loc並以相同的方式讀寫。在字符串中,每個數組都是通過遞增索引來讀取的,然後將壓縮值寫入文件寫入文件中。在文件中,它被讀爲二進制(wb),在字符串中它被讀爲數組元素。那會有什麼問題嗎?需要專家的意見。

+0

你能通過樣本輸入和輸出來擴充你的MCVE嗎?你能描述你在代碼中所做的更多更多細節嗎?我假設您發佈的代碼是您更改的版本,鏈接中的代碼是原創的,是真的? – Yunnosch

+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); 
} 

我通過在代碼片段中添加行來解決它。我需要添加解決問題的位緩衝區的最後一位。