Home » pdfbox-1.1.0-src » org.apache.pdfbox.io » [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.io;
   18   
   19   import java.io.FilterOutputStream;
   20   import java.io.IOException;
   21   import java.io.OutputStream;
   22   
   23   /**
   24    * This class represents an ASCII85 output stream.
   25    *
   26    * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
   27    * @version $Revision: 1.7 $
   28    */
   29   public class ASCII85OutputStream extends FilterOutputStream
   30   {
   31   
   32       private int lineBreak;
   33       private int count;
   34   
   35       private byte[] indata;
   36       private byte[] outdata;
   37   
   38       /**
   39        * Function produces five ASCII printing characters from
   40        * four bytes of binary data.
   41        */
   42       private int maxline;
   43       private boolean flushed;
   44       private char terminator;
   45   
   46       /**
   47        * Constructor.
   48        *
   49        * @param out The output stream to write to.
   50        */
   51       public ASCII85OutputStream( OutputStream out )
   52       {
   53           super( out );
   54           lineBreak = 36*2;
   55           maxline = 36*2;
   56           count=0;
   57           indata=new byte[4];
   58           outdata=new byte[5];
   59           flushed=true;
   60           terminator='~';
   61       }
   62   
   63       /**
   64        * This will set the terminating character.
   65        *
   66        * @param term The terminating character.
   67        */
   68       public void setTerminator(char term)
   69       {
   70           if(term<118 || term>126 || term=='z')
   71           {
   72               throw new IllegalArgumentException("Terminator must be 118-126 excluding z");
   73           }
   74           terminator=term;
   75       }
   76   
   77       /**
   78        * This will get the terminating character.
   79        *
   80        * @return The terminating character.
   81        */
   82       public char getTerminator()
   83       {
   84           return terminator;
   85       }
   86   
   87       /**
   88        * This will set the line length that will be used.
   89        *
   90        * @param l The length of the line to use.
   91        */
   92       public void setLineLength(int l)
   93       {
   94           if( lineBreak > l )
   95           {
   96               lineBreak = l;
   97           }
   98           maxline=l;
   99       }
  100   
  101       /**
  102        * This will get the length of the line.
  103        *
  104        * @return The line length attribute.
  105        */
  106       public int getLineLength()
  107       {
  108           return maxline;
  109       }
  110   
  111       /**
  112        * This will transform the next four ascii bytes.
  113        */
  114       private final void  transformASCII85()
  115       {
  116           long word;
  117           word=( (((indata[0] << 8) | (indata[1] &0xFF)) << 16) |
  118           ( (indata[2] & 0xFF) << 8) | (indata[3] & 0xFF)
  119           )    & 0xFFFFFFFFL;
  120           // System.out.println("word=0x"+Long.toString(word,16)+" "+word);
  121   
  122           if (word == 0 )
  123           {
  124               outdata[0]=(byte)'z';
  125               outdata[1]=0;
  126               return;
  127           }
  128           long x;
  129           x=word/(85L*85L*85L*85L);
  130           // System.out.println("x0="+x);
  131           outdata[0]=(byte)(x+'!');
  132           word-=x*85L*85L*85L*85L;
  133   
  134           x=word/(85L*85L*85L);
  135           // System.out.println("x1="+x);
  136           outdata[1]=(byte)(x+'!');
  137           word-=x*85L*85L*85L;
  138   
  139           x=word/(85L*85L);
  140           // System.out.println("x2="+x);
  141           outdata[2]=(byte)(x+'!');
  142           word-=x*85L*85L;
  143   
  144           x=word/85L;
  145           // System.out.println("x3="+x);
  146           outdata[3]=(byte)(x+'!');
  147   
  148           // word-=x*85L;
  149   
  150           // System.out.println("x4="+(word % 85L));
  151           outdata[4]=(byte)((word%85L)+'!');
  152       }
  153   
  154       /**
  155        * This will write a single byte.
  156        *
  157        * @param b The byte to write.
  158        *
  159        * @throws IOException If there is an error writing to the stream.
  160        */
  161       public final void write(int b) throws IOException
  162       {
  163           flushed=false;
  164           indata[count++]=(byte)b;
  165           if(count < 4 )
  166           {
  167               return;
  168           }
  169           transformASCII85();
  170           for(int i=0;i<5;i++)
  171           {
  172               if(outdata[i]==0)
  173               {
  174                   break;
  175               }
  176               out.write(outdata[i]);
  177               if(--lineBreak==0)
  178               {
  179                   out.write('\n');
  180                   lineBreak=maxline;
  181               }
  182           }
  183           count = 0;
  184       }
  185   
  186       /**
  187        * This will write a chunk of data to the stream.
  188        *
  189        * @param b The byte buffer to read from.
  190        * @param off The offset into the buffer.
  191        * @param sz The number of bytes to read from the buffer.
  192        *
  193        * @throws IOException If there is an error writing to the underlying stream.
  194        */
  195       public final void write(byte[] b,int off, int sz) throws IOException
  196       {
  197           for(int i=0;i<sz;i++)
  198           {
  199               if(count < 3)
  200               {
  201                   indata[count++]=b[off+i];
  202               }
  203               else
  204               {
  205                   write(b[off+i]);
  206               }
  207           }
  208       }
  209   
  210       /**
  211        * This will flush the data to the stream.
  212        *
  213        * @throws IOException If there is an error writing the data to the stream.
  214        */
  215       public final void flush() throws IOException
  216       {
  217           if(flushed)
  218           {
  219               return;
  220           }
  221           if(count > 0 )
  222           {
  223               for( int i=count; i<4; i++ )
  224               {
  225                   indata[i]=0;
  226               }
  227               transformASCII85();
  228               if(outdata[0]=='z')
  229               {
  230                   for(int i=0;i<5;i++) // expand 'z',
  231                   {
  232                       outdata[i]=(byte)'!';
  233                   }
  234               }
  235               for(int i=0;i<count+1;i++)
  236               {
  237                   out.write(outdata[i]);
  238                   if(--lineBreak==0)
  239                   {
  240                       out.write('\n');
  241                       lineBreak=maxline;
  242                   }
  243               }
  244           }
  245           if(--lineBreak==0)
  246           {
  247               out.write('\n');
  248           }
  249           out.write(terminator);
  250           out.write('\n');
  251           count = 0;
  252           lineBreak=maxline;
  253           flushed=true;
  254           super.flush();
  255       }
  256   
  257       /**
  258        * This will close the stream.
  259        *
  260        * @throws IOException If there is an error closing the wrapped stream.
  261        */
  262       public void close() throws IOException
  263       {
  264           try
  265           {
  266               super.close();
  267           }
  268           finally
  269           {
  270               indata=outdata=null;
  271           }
  272       }
  273   
  274       /**
  275        * This will flush the stream.
  276        *
  277        * @throws Throwable If there is an error.
  278        */
  279       protected void finalize() throws Throwable
  280       {
  281           try
  282           {
  283               flush();
  284           }
  285           finally
  286           {
  287               super.finalize();
  288           }
  289       }
  290   }

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