簡體   English   中英

LZW編碼器解碼器-符號表

[英]LZW Encoder Decoder - Symbol Table

當我使用長度為256的符號表(字典)時,我的LZW壓縮可以工作,編碼器和解碼器都可以使用256,並且一切正常,但是當我將該數字增加到512、1024、4096時,解碼后的文件輸出不一樣與第一個輸入文件...有任何提示嗎?

源代碼:

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

您正在讀取字節,它們無法存儲更大的值。 如果要使用大於255的代碼進行LZW,則需要對位流進行編碼,或者為了測試(作為臨時技巧)編寫兩個字節的字(大小為16的無符號整數)。

更換

writer.write ( codeword );

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

並檢查是否有效。 如果是這樣,您可以花一些時間來實現基於位的流。 您還需要更新閱讀器和解碼器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM