KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > pdfbox > io > ASCII85OutputStream


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.io;
32
33 import java.io.FilterOutputStream JavaDoc;
34 import java.io.IOException JavaDoc;
35 import java.io.OutputStream JavaDoc;
36
37 /**
38  * This class represents an ASCII85 output stream.
39  *
40  * @author <a HREF="mailto:ben@benlitchfield.com">Ben Litchfield</a>
41  * @version $Revision: 1.7 $
42  */

43 public class ASCII85OutputStream extends FilterOutputStream JavaDoc
44 {
45
46     private int lineBreak;
47     private int count;
48
49     private byte[] indata;
50     private byte[] outdata;
51
52     /**
53      * Function produces five ASCII printing characters from
54      * four bytes of binary data.
55      */

56     private int maxline;
57     private boolean flushed;
58     private char terminator;
59
60     /**
61      * Constructor.
62      *
63      * @param out The output stream to write to.
64      */

65     public ASCII85OutputStream( OutputStream JavaDoc out )
66     {
67         super( out );
68         lineBreak = 36*2;
69         maxline = 36*2;
70         count=0;
71         indata=new byte[4];
72         outdata=new byte[5];
73         flushed=true;
74         terminator='~';
75     }
76
77     /**
78      * This will set the terminating character.
79      *
80      * @param term The terminating character.
81      */

82     public void setTerminator(char term)
83     {
84         if(term<118 || term>126 || term=='z')
85         {
86             throw new IllegalArgumentException JavaDoc("Terminator must be 118-126 excluding z");
87         }
88         terminator=term;
89     }
90
91     /**
92      * This will get the terminating character.
93      *
94      * @return The terminating character.
95      */

96     public char getTerminator()
97     {
98         return terminator;
99     }
100
101     /**
102      * This will set the line length that will be used.
103      *
104      * @param l The length of the line to use.
105      */

106     public void setLineLength(int l)
107     {
108         if( lineBreak > l )
109         {
110             lineBreak = l;
111         }
112         maxline=l;
113     }
114
115     /**
116      * This will get the length of the line.
117      *
118      * @return The line length attribute.
119      */

120     public int getLineLength()
121     {
122         return maxline;
123     }
124
125     /**
126      * This will transform the next four ascii bytes.
127      */

128     private final void transformASCII85()
129     {
130         long word;
131         word=( (((indata[0] << 8) | (indata[1] &0xFF)) << 16) |
132         ( (indata[2] & 0xFF) << 8) | (indata[3] & 0xFF)
133         ) & 0xFFFFFFFFL;
134         // System.out.println("word=0x"+Long.toString(word,16)+" "+word);
135

136         if (word == 0 )
137         {
138             outdata[0]=(byte)'z';
139             outdata[1]=0;
140             return;
141         }
142         long x;
143         x=word/(85L*85L*85L*85L);
144         // System.out.println("x0="+x);
145
outdata[0]=(byte)(x+'!');
146         word-=x*85L*85L*85L*85L;
147
148         x=word/(85L*85L*85L);
149         // System.out.println("x1="+x);
150
outdata[1]=(byte)(x+'!');
151         word-=x*85L*85L*85L;
152
153         x=word/(85L*85L);
154         // System.out.println("x2="+x);
155
outdata[2]=(byte)(x+'!');
156         word-=x*85L*85L;
157
158         x=word/85L;
159         // System.out.println("x3="+x);
160
outdata[3]=(byte)(x+'!');
161
162         // word-=x*85L;
163

164         // System.out.println("x4="+(word % 85L));
165
outdata[4]=(byte)((word%85L)+'!');
166     }
167
168     /**
169      * This will write a single byte.
170      *
171      * @param b The byte to write.
172      *
173      * @throws IOException If there is an error writing to the stream.
174      */

175     public final void write(int b) throws IOException JavaDoc
176     {
177         flushed=false;
178         indata[count++]=(byte)b;
179         if(count < 4 )
180         {
181             return;
182         }
183         transformASCII85();
184         for(int i=0;i<5;i++)
185         {
186             if(outdata[i]==0)
187             {
188                 break;
189             }
190             out.write(outdata[i]);
191             if(--lineBreak==0)
192             {
193                 out.write('\n');
194                 lineBreak=maxline;
195             }
196         }
197         count = 0;
198     }
199
200     /**
201      * This will write a chunk of data to the stream.
202      *
203      * @param b The byte buffer to read from.
204      * @param off The offset into the buffer.
205      * @param sz The number of bytes to read from the buffer.
206      *
207      * @throws IOException If there is an error writing to the underlying stream.
208      */

209     public final void write(byte[] b,int off, int sz) throws IOException JavaDoc
210     {
211         for(int i=0;i<sz;i++)
212         {
213             if(count < 3)
214             {
215                 indata[count++]=b[off+i];
216             }
217             else
218             {
219                 write(b[off+i]);
220             }
221         }
222     }
223
224     /**
225      * This will flush the data to the stream.
226      *
227      * @throws IOException If there is an error writing the data to the stream.
228      */

229     public final void flush() throws IOException JavaDoc
230     {
231         if(flushed)
232         {
233             return;
234         }
235         if(count > 0 )
236         {
237             for( int i=count; i<4; i++ )
238             {
239                 indata[i]=0;
240             }
241             transformASCII85();
242             if(outdata[0]=='z')
243             {
244                 for(int i=0;i<5;i++) // expand 'z',
245
{
246                     outdata[i]=(byte)'!';
247                 }
248             }
249             for(int i=0;i<count+1;i++)
250             {
251                 out.write(outdata[i]);
252                 if(--lineBreak==0)
253                 {
254                     out.write('\n');
255                     lineBreak=maxline;
256                 }
257             }
258         }
259         if(--lineBreak==0)
260         {
261             out.write('\n');
262         }
263         out.write(terminator);
264         out.write('\n');
265         count = 0;
266         lineBreak=maxline;
267         flushed=true;
268         super.flush();
269     }
270
271     /**
272      * This will close the stream.
273      *
274      * @throws IOException If there is an error closing the wrapped stream.
275      */

276     public void close() throws IOException JavaDoc
277     {
278         try
279         {
280             super.close();
281         }
282         finally
283         {
284             indata=outdata=null;
285         }
286     }
287
288     /**
289      * This will flush the stream.
290      *
291      * @throws Throwable If there is an error.
292      */

293     protected void finalize() throws Throwable JavaDoc
294     {
295         try
296         {
297             flush();
298         }
299         finally
300         {
301             super.finalize();
302         }
303     }
304 }
Popular Tags