KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pdfbox > filter > LZWDictionary


1 /**
2  * Copyright (c) 2003, www.pdfbox.org
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * 3. Neither the name of pdfbox; nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * http://www.pdfbox.org
29  *
30  */

31 package org.pdfbox.filter;
32
33 import java.io.ByteArrayOutputStream JavaDoc;
34 import java.io.IOException JavaDoc;
35
36 import java.util.HashMap JavaDoc;
37 import java.util.Map JavaDoc;
38
39 /**
40  * This is the used for the LZWDecode filter. This represents the dictionary mappings
41  * between codes and their values.
42  *
43  * @author <a HREF="mailto:ben@benlitchfield.com">Ben Litchfield</a>
44  * @version $Revision: 1.4 $
45  */

46 class LZWDictionary
47 {
48     private Map JavaDoc codeToData = new HashMap JavaDoc();
49     private LZWNode root = new LZWNode();
50
51     private ByteArrayOutputStream JavaDoc buffer = new ByteArrayOutputStream JavaDoc();
52     private long nextCode = 258;
53     private int codeSize = 9;
54
55     /**
56      * constructor.
57      */

58     public LZWDictionary()
59     {
60         for( long i=0; i<256; i++ )
61         {
62             LZWNode node = new LZWNode();
63             node.setCode( i );
64             root.setNode( (byte)i, node );
65             codeToData.put( new Long JavaDoc( i ), new byte[]{ (byte)i } );
66         }
67     }
68
69     /**
70      * This will get the value for the code. It will return null if the code is not
71      * defined.
72      *
73      * @param code The key to the data.
74      *
75      * @return The data that is mapped to the code.
76      */

77     public byte[] getData( long code )
78     {
79         return (byte[])codeToData.get( new Long JavaDoc( code ) );
80     }
81
82     /**
83      * This will take a visit from a byte[]. This will create new code entries as
84      * necessary.
85      *
86      * @param data The byte to get a visit from.
87      *
88      * @throws IOException If there is an error visiting this data.
89      */

90     public void visit( byte[] data ) throws IOException JavaDoc
91     {
92         for( int i=0; i<data.length; i++ )
93         {
94             visit( data[i] );
95         }
96     }
97
98     /**
99      * This will take a visit from a byte. This will create new code entries as
100      * necessary.
101      *
102      * @param data The byte to get a visit from.
103      *
104      * @throws IOException If there is an error visiting this data.
105      */

106     public void visit( byte data ) throws IOException JavaDoc
107     {
108         buffer.write( data );
109         byte[] curBuffer = buffer.toByteArray();
110         LZWNode previous = null;
111         LZWNode current = root;
112         boolean createNewCode = false;
113         for( int i=0; i<curBuffer.length && current != null; i++ )
114         {
115             previous = current;
116             current = current.getNode( curBuffer[i] );
117             if( current == null )
118             {
119                 createNewCode = true;
120                 current = new LZWNode();
121                 previous.setNode( curBuffer[i], current );
122             }
123         }
124         if( createNewCode )
125         {
126             long code = nextCode++;
127             current.setCode( code );
128             codeToData.put( new Long JavaDoc( code ), curBuffer );
129
130             /**
131             System.out.print( "Adding " + code + "='" );
132             for( int i=0; i<curBuffer.length; i++ )
133             {
134                 String hex = Integer.toHexString( ((curBuffer[i]+256)%256) );
135                 if( hex.length() <=1 )
136                 {
137                     hex = "0" + hex;
138                 }
139                 if( i != curBuffer.length -1 )
140                 {
141                     hex += " ";
142                 }
143                 System.out.print( hex.toUpperCase() );
144             }
145             System.out.println( "'" );
146             **/

147             buffer.reset();
148             buffer.write( data );
149             resetCodeSize();
150         }
151     }
152
153     /**
154      * This will get the next code that will be created.
155      *
156      * @return The next code to be created.
157      */

158     public long getNextCode()
159     {
160         return nextCode;
161     }
162
163     /**
164      * This will get the size of the code in bits, 9, 10, or 11.
165      *
166      * @return The size of the code in bits.
167      */

168     public int getCodeSize()
169     {
170         return codeSize;
171     }
172
173     /**
174      * This will determine the code size.
175      */

176     private void resetCodeSize()
177     {
178         if( nextCode >= 2048 )
179         {
180             codeSize = 12;
181         }
182         else if( nextCode >= 1024 )
183         {
184             codeSize = 11;
185         }
186         else if( nextCode >= 512 )
187         {
188             codeSize = 10;
189         }
190         else
191         {
192             codeSize = 9;
193         }
194     }
195
196     /**
197      * This will crear the internal buffer that the dictionary uses.
198      */

199     public void clear()
200     {
201         buffer.reset();
202     }
203
204     /**
205      * This will folow the path to the data node.
206      *
207      * @param data The path to the node.
208      *
209      * @return The node that resides at that path.
210      */

211     public LZWNode getNode( byte[] data )
212     {
213         return root.getNode( data );
214     }
215 }
Popular Tags