Home » pdfbox-1.1.0-src » org.apache.pdfbox.filter » [javadoc | source]

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   package org.apache.pdfbox.filter;
   18   
   19   import java.io.ByteArrayOutputStream;
   20   import java.io.IOException;
   21   
   22   import java.util.HashMap;
   23   import java.util.Map;
   24   
   25   /**
   26    * This is the used for the LZWDecode filter.  This represents the dictionary mappings
   27    * between codes and their values.
   28    *
   29    * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
   30    * @version $Revision: 1.4 $
   31    */
   32   class LZWDictionary
   33   {
   34       private Map codeToData = new HashMap();
   35       private LZWNode root = new LZWNode();
   36   
   37       private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
   38       private long nextCode = 258;
   39       private int codeSize = 9;
   40   
   41       /**
   42        * constructor.
   43        */
   44       public LZWDictionary()
   45       {
   46           for( long i=0; i<256; i++ )
   47           {
   48               LZWNode node = new LZWNode();
   49               node.setCode( i );
   50               root.setNode( (byte)i, node );
   51               codeToData.put( new Long( i ), new byte[]{ (byte)i } );
   52           }
   53       }
   54   
   55       /**
   56        * This will get the value for the code.  It will return null if the code is not
   57        * defined.
   58        *
   59        * @param code The key to the data.
   60        *
   61        * @return The data that is mapped to the code.
   62        */
   63       public byte[] getData( long code )
   64       {
   65           return (byte[])codeToData.get( new Long( code ) );
   66       }
   67   
   68       /**
   69        * This will take a visit from a byte[].  This will create new code entries as
   70        * necessary.
   71        *
   72        * @param data The byte to get a visit from.
   73        *
   74        * @throws IOException If there is an error visiting this data.
   75        */
   76       public void visit( byte[] data ) throws IOException
   77       {
   78           for( int i=0; i<data.length; i++ )
   79           {
   80               visit( data[i] );
   81           }
   82       }
   83   
   84       /**
   85        * This will take a visit from a byte.  This will create new code entries as
   86        * necessary.
   87        *
   88        * @param data The byte to get a visit from.
   89        *
   90        * @throws IOException If there is an error visiting this data.
   91        */
   92       public void visit( byte data ) throws IOException
   93       {
   94           buffer.write( data );
   95           byte[] curBuffer = buffer.toByteArray();
   96           LZWNode previous = null;
   97           LZWNode current = root;
   98           boolean createNewCode = false;
   99           for( int i=0; i<curBuffer.length && current != null; i++ )
  100           {
  101               previous = current;
  102               current = current.getNode( curBuffer[i] );
  103               if( current == null )
  104               {
  105                   createNewCode = true;
  106                   current = new LZWNode();
  107                   previous.setNode( curBuffer[i], current );
  108               }
  109           }
  110           if( createNewCode )
  111           {
  112               long code = nextCode++;
  113               current.setCode( code );
  114               codeToData.put( new Long( code ), curBuffer );
  115   
  116               /**
  117               System.out.print( "Adding " + code + "='" );
  118               for( int i=0; i<curBuffer.length; i++ )
  119               {
  120                   String hex = Integer.toHexString( ((curBuffer[i]+256)%256) );
  121                   if( hex.length() <=1 )
  122                   {
  123                       hex = "0" + hex;
  124                   }
  125                   if( i != curBuffer.length -1 )
  126                   {
  127                       hex += " ";
  128                   }
  129                   System.out.print( hex.toUpperCase() );
  130               }
  131               System.out.println( "'" );
  132               **/
  133               buffer.reset();
  134               buffer.write( data );
  135               resetCodeSize();
  136           }
  137       }
  138   
  139       /**
  140        * This will get the next code that will be created.
  141        *
  142        * @return The next code to be created.
  143        */
  144       public long getNextCode()
  145       {
  146           return nextCode;
  147       }
  148   
  149       /**
  150        * This will get the size of the code in bits, 9, 10, or 11.
  151        *
  152        * @return The size of the code in bits.
  153        */
  154       public int getCodeSize()
  155       {
  156           return codeSize;
  157       }
  158   
  159       /**
  160        * This will determine the code size.
  161        */
  162       private void resetCodeSize()
  163       {
  164           if( nextCode >= 2048 )
  165           {
  166               codeSize = 12;
  167           }
  168           else if( nextCode >= 1024 )
  169           {
  170               codeSize = 11;
  171           }
  172           else if( nextCode >= 512 )
  173           {
  174               codeSize = 10;
  175           }
  176           else
  177           {
  178               codeSize = 9;
  179           }
  180       }
  181   
  182       /**
  183        * This will crear the internal buffer that the dictionary uses.
  184        */
  185       public void clear()
  186       {
  187           buffer.reset();
  188       }
  189   
  190       /**
  191        * This will folow the path to the data node.
  192        *
  193        * @param data The path to the node.
  194        *
  195        * @return The node that resides at that path.
  196        */
  197       public LZWNode getNode( byte[] data )
  198       {
  199           return root.getNode( data );
  200       }
  201   }

Home » pdfbox-1.1.0-src » org.apache.pdfbox.filter » [javadoc | source]