2013-06-25 67 views
0

当我使用长度为256的符号表(字典)时,编码器和解码器都与256一起工作,并且一切正常,但是当我将此数字增加到512,1024, 4096解码后的文件输出与第一个输入文件不一样......任何提示?LZW编码器解码器 - 符号表

源码:

LZWEncoder.java:

import java .io .*; 
public class LZWEncoder 
{ 
    public static void main (String [] args) 
      throws FileNotFoundException , IOException 
      { 
     File file = new File ("calgary/book1"); 
     File fileOut = new File ("calgary/book1_enc"); 
     FileInputStream reader = new FileInputStream (file); 
     FileOutputStream writer = new FileOutputStream (fileOut); 
     int size_st; 
     long file_size; 
     file_size = file.length(); 
     size_st = (int) file_size/1024; 
     System.out.println("File size " + file_size + " Sysmbol tree" + size_st); 

     if (size_st < 256) 
      size_st = 256; 
     else if (size_st < 512) 
      size_st = 512; 
     else if (size_st < 1024) 
      size_st = 1024; 
     else if (size_st < 2048) 
      size_st = 2048; 
     else 
      size_st = 4096; 

     byte[] size_stInBytes = (Integer.toString(size_st)+"\n").getBytes(); 
    // writer.write(size_stInBytes); 

     System.out.println("File size " + file_size + " Sysmbol tree " + size_st); 

     // input stream with lookahead 
     LookAheadIn in = new LookAheadIn (file); 
     LZWst st = new LZWst (4096); // specialised ST 
     while (! in.isEmpty()) 
     { 
      int codeword = st.getput (in); 
      writer.write (codeword); 
     } 
     writer.close(); 
     reader.close(); 
      } 
} 

LZWDecoder.java:

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.util.Scanner; 


public class LZWDecoder 
{ 
    public static void main (String [] args) 
      throws FileNotFoundException , IOException 
      { 
     File file = new File ("calgary/book1_enc"); 
     Scanner first_line = new Scanner("calgary/book1_enc"); 
     File fileOut = new File ("calgary/book1_dec2"); 
     FileInputStream reader = new FileInputStream (file); 
     FileOutputStream writer = new FileOutputStream (fileOut); 
     String size_st; 
     size_st =first_line.nextLine(); 
     System.out.println(" Sysmbol tree " + size_st); 
     String [] st = new String [4096]; 
     int i; 
     for (i=0; i <128; i++) 
      st[i] = Character.toString ((char) i); 

     String prev = ""; 
     int codeword ; 
     while ((codeword = reader.read())!= -1) 
     { 

      String s; 
      if (codeword == i) // Tricky situation ! 
       s = prev + prev.charAt(0); 
      else 
       s = st[codeword ]; 
      for (int j = 0; j<s.length(); j++) 
       writer.write(s.charAt (j)); 
      if (prev.length() > 0 && i < 4096) 
       st[i++] = prev + s.charAt(0); 
      prev = s; 
     } 
     writer.close(); 
     reader.close(); 
      } 
} 

LZWst.java:

import java.io.FileNotFoundException; 
import java.io.IOException; 

public class LZWst 
{ 
    private int i; // next codeword to assign 
    private int codeword ; // codeword to return 
    private Node [] roots ; // array of TSTs 
    private int st_size; 
    public LZWst (int st_sz) 
    { 
     st_size = st_sz; 
     roots = new Node [128]; 
     for (i=0; i <128; i++) // init with ASCII 
      roots [i] = new Node ((char) i,i); 
    } 
    private class Node 
    { // standard node code 
     Node (int c, int codeword) 
     { 
      this .c = c; 
      this . codeword = codeword ; 
     } 
     int c; 
     Node left , mid , right ; 
     int codeword ; 
    } 

    public int getput (LookAheadIn in) 
      throws FileNotFoundException , IOException 
      { 
     int c = in. readChar(); 
     if (c == -1) return -1; // EOF 
     roots [c] = getput (c, roots [c],in); 
     in. backup(); 
     return codeword ; // longest prefix 
      } 
    public Node getput (int c, Node x, LookAheadIn in) 
      throws FileNotFoundException , IOException 
      { // recursive search *and* insert 
     if (x== null) { 
      if (i<st_size){ 
      x = new Node (c,i++); 
      System.out.println("Value of i: " + i); 
      } 
      return x; 
     } 
     if (c<x.c) x. left = getput (c,x.left ,in); 
     else if (c>x.c) x. right = getput (c,x.right ,in); 
     else { 
      int next = in.readChar(); 
      codeword = x. codeword ; 
      x.mid = getput (next ,x.mid ,in); 
     } 
     return x; 
      } 
} 

LookAheadIn.java:

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 

public class LookAheadIn 
{ 
    private FileInputStream in = null ; 
    private int last ; 
    private boolean backup = true ; 
    public LookAheadIn (File file) 
      throws FileNotFoundException , IOException 
      { 
     in = new FileInputStream (file); 
     last = in. read(); 
     backup = true ; 
      } 
    public void backup() { backup = true ; } 
    public int readChar() throws FileNotFoundException , IOException 
      { 
     if (! backup) last = in. read(); 
     backup = false ; 
     return last ;} 
    public boolean isEmpty(){ return last == -1; } 
} 

回答

1

您正在读取字节,它们无法存储更大的值。如果你想使用大于255的代码来执行LZW,则需要对比特流进行编码,或者对测试(作为临时攻击)写入两个字节的字(大小为16的无符号整数)。

更换

writer.write (codeword); 

writer.write (codeword>>8); 
writer.write (codeword&0xff); 

,并检查是否正常工作。如果是这样,你可以花一些时间来实现一个基于位流的流。您还需要更新阅读器和解码器。