View Javadoc

1   package org.apache.maven.doxia.module.rtf;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.BufferedInputStream;
23  import java.io.BufferedReader;
24  import java.io.EOFException;
25  import java.io.FileInputStream;
26  import java.io.IOException;
27  import java.io.InputStream;
28  import java.io.InputStreamReader;
29  import java.io.Reader;
30  
31  /**
32   * <a href="http://en.wikipedia.org/wiki/Portable_pixmap">PBM</a> images reader.
33   *
34   * @version $Id: PBMReader.java 724307 2008-12-08 11:15:00Z vsiveton $
35   */
36  class PBMReader
37  {
38      static final int TYPE_PBM = 1;
39  
40      static final int TYPE_PGM = 2;
41  
42      static final int TYPE_PPM = 3;
43  
44      private static final String BAD_FILE_FORMAT = "bad file format";
45  
46      private static final String UNSUPPORTED_TYPE = "unsupported file type";
47  
48      private static final String UNSUPPORTED_FORMAT = "unsupported data format";
49  
50      private static final String UNSUPPORTED_DEPTH = "unsupported color depth";
51  
52      protected int type;
53  
54      protected boolean binary;
55  
56      protected int width;
57  
58      protected int height;
59  
60      protected int maxValue;
61  
62      private int bytesPerLine;
63  
64      private InputStream stream;
65  
66      PBMReader( String fileName )
67          throws Exception
68      {
69          HeaderReader header = new HeaderReader();
70  
71          int length = header.read( fileName );
72  
73          if ( type != TYPE_PPM )
74          {
75              throw new Exception( UNSUPPORTED_TYPE );
76          }
77  
78          if ( !binary )
79          {
80              throw new Exception( UNSUPPORTED_FORMAT );
81          }
82  
83          if ( maxValue > 255 )
84          {
85              throw new Exception( UNSUPPORTED_DEPTH );
86          }
87  
88          switch ( type )
89          {
90              case TYPE_PBM:
91                  bytesPerLine = ( width + 7 ) / 8;
92                  break;
93              case TYPE_PGM:
94                  bytesPerLine = width;
95                  break;
96              case TYPE_PPM:
97                  bytesPerLine = 3 * width;
98                  break;
99          }
100 
101         stream = new BufferedInputStream( new FileInputStream( fileName ) );
102 
103         skip( length );
104     }
105 
106     int type()
107     {
108         return type;
109     }
110 
111     int width()
112     {
113         return width;
114     }
115 
116     int height()
117     {
118         return height;
119     }
120 
121     int maxValue()
122     {
123         return maxValue;
124     }
125 
126     int bytesPerLine()
127     {
128         return bytesPerLine;
129     }
130 
131     long skip( long count )
132         throws IOException
133     {
134         long skipped = stream.skip( count );
135 
136         if ( skipped < count )
137         {
138             byte[] b = new byte[512];
139             while ( skipped < count )
140             {
141                 int len = (int) Math.min( b.length, ( count - skipped ) );
142                 int n = stream.read( b, 0, len );
143                 if ( n < 0 )
144                 {
145                     break; // end of file
146                 }
147                 skipped += n;
148             }
149         }
150 
151         return skipped;
152     }
153 
154     int read( byte[] b, int off, int len )
155         throws IOException
156     {
157         int count = 0;
158         while ( count < len )
159         {
160             int n = stream.read( b, off + count, len - count );
161             if ( n < 0 )
162             {
163                 break; // end of file
164             }
165             count += n;
166         }
167         return count;
168     }
169 
170     // -----------------------------------------------------------------------
171 
172     class HeaderReader
173     {
174 
175         private Reader reader;
176 
177         private int offset;
178 
179         int read( String fileName )
180             throws Exception
181         {
182             String field;
183 
184             reader = new BufferedReader( new InputStreamReader( new FileInputStream( fileName ), "US-ASCII" ) );
185             offset = 0;
186 
187             field = getField();
188             if ( field.length() != 2 || field.charAt( 0 ) != 'P' )
189             {
190                 reader.close();
191                 throw new Exception( BAD_FILE_FORMAT );
192             }
193             switch ( field.charAt( 1 ) )
194             {
195                 case '1':
196                 case '4':
197                     type = TYPE_PBM;
198                     break;
199                 case '2':
200                 case '5':
201                     type = TYPE_PGM;
202                     break;
203                 case '3':
204                 case '6':
205                     type = TYPE_PPM;
206                     break;
207                 default:
208                     reader.close();
209                     throw new Exception( BAD_FILE_FORMAT );
210             }
211             if ( field.charAt( 1 ) > '3' )
212             {
213                 binary = true;
214             }
215             else
216             {
217                 binary = false;
218             }
219 
220             try
221             {
222                 width = Integer.parseInt( getField() );
223                 height = Integer.parseInt( getField() );
224                 if ( type == TYPE_PBM )
225                 {
226                     maxValue = 1;
227                 }
228                 else
229                 {
230                     maxValue = Integer.parseInt( getField() );
231                 }
232             }
233             catch ( NumberFormatException e )
234             {
235                 reader.close();
236                 throw new Exception( BAD_FILE_FORMAT );
237             }
238 
239             reader.close();
240 
241             return offset;
242         }
243 
244         private String getField()
245             throws IOException
246         {
247             char c;
248             StringBuffer field = new StringBuffer();
249 
250             try
251             {
252                 do
253                 {
254                     while ( ( c = getChar() ) == '#' )
255                     {
256                         skipComment();
257                     }
258                 }
259                 while ( Character.isWhitespace( c ) );
260 
261                 field.append( c );
262 
263                 while ( !Character.isWhitespace( c = getChar() ) )
264                 {
265                     if ( c == '#' )
266                     {
267                         skipComment();
268                         break;
269                     }
270                     field.append( c );
271                 }
272             }
273             catch ( EOFException ignore )
274             {
275                 // nop
276             }
277 
278             return field.toString();
279         }
280 
281         private char getChar()
282             throws IOException, EOFException
283         {
284             int c = reader.read();
285             if ( c < 0 )
286             {
287                 throw new EOFException();
288             }
289             offset += 1;
290             return (char) c;
291         }
292 
293         private void skipComment()
294             throws IOException
295         {
296             try
297             {
298                 while ( getChar() != '\n' )
299                 {
300                     ;
301                 }
302             }
303             catch ( EOFException ignore )
304             {
305                 // nop
306             }
307         }
308     }
309 }