1 package org.apache.maven.doxia.module.rtf;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 import java.nio.charset.StandardCharsets;
31
32
33
34
35 class PBMReader
36 {
37 static final int TYPE_PBM = 1;
38
39 static final int TYPE_PGM = 2;
40
41 static final int TYPE_PPM = 3;
42
43 private static final String BAD_FILE_FORMAT = "bad file format";
44
45 private static final String UNSUPPORTED_TYPE = "unsupported file type";
46
47 private static final String UNSUPPORTED_FORMAT = "unsupported data format";
48
49 private static final String UNSUPPORTED_DEPTH = "unsupported color depth";
50
51 protected int type;
52
53 protected boolean binary;
54
55 protected int width;
56
57 protected int height;
58
59 protected int maxValue;
60
61 private int bytesPerLine;
62
63 private InputStream stream;
64
65 PBMReader( String fileName )
66 throws Exception
67 {
68 HeaderReader header = new HeaderReader();
69
70 int length = header.read( fileName );
71
72 if ( type != TYPE_PPM )
73 {
74 throw new Exception( UNSUPPORTED_TYPE );
75 }
76
77 if ( !binary )
78 {
79 throw new Exception( UNSUPPORTED_FORMAT );
80 }
81
82 if ( maxValue > 255 )
83 {
84 throw new Exception( UNSUPPORTED_DEPTH );
85 }
86
87 switch ( type )
88 {
89 case TYPE_PBM:
90 bytesPerLine = ( width + 7 ) / 8;
91 break;
92 case TYPE_PGM:
93 bytesPerLine = width;
94 break;
95 case TYPE_PPM:
96 bytesPerLine = 3 * width;
97 break;
98 default:
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;
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;
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(
185 new FileInputStream( fileName ), StandardCharsets.US_ASCII ) );
186 offset = 0;
187
188 field = getField();
189 if ( field.length() != 2 || field.charAt( 0 ) != 'P' )
190 {
191 reader.close();
192 throw new Exception( BAD_FILE_FORMAT );
193 }
194 switch ( field.charAt( 1 ) )
195 {
196 case '1':
197 case '4':
198 type = TYPE_PBM;
199 break;
200 case '2':
201 case '5':
202 type = TYPE_PGM;
203 break;
204 case '3':
205 case '6':
206 type = TYPE_PPM;
207 break;
208 default:
209 reader.close();
210 throw new Exception( BAD_FILE_FORMAT );
211 }
212 if ( field.charAt( 1 ) > '3' )
213 {
214 binary = true;
215 }
216 else
217 {
218 binary = false;
219 }
220
221 try
222 {
223 width = Integer.parseInt( getField() );
224 height = Integer.parseInt( getField() );
225 if ( type == TYPE_PBM )
226 {
227 maxValue = 1;
228 }
229 else
230 {
231 maxValue = Integer.parseInt( getField() );
232 }
233 }
234 catch ( NumberFormatException e )
235 {
236 reader.close();
237 throw new Exception( BAD_FILE_FORMAT );
238 }
239
240 reader.close();
241
242 return offset;
243 }
244
245 private String getField()
246 throws IOException
247 {
248 char c;
249 StringBuilder field = new StringBuilder();
250
251 try
252 {
253 do
254 {
255 while ( ( c = getChar() ) == '#' )
256 {
257 skipComment();
258 }
259 }
260 while ( Character.isWhitespace( c ) );
261
262 field.append( c );
263
264 while ( !Character.isWhitespace( c = getChar() ) )
265 {
266 if ( c == '#' )
267 {
268 skipComment();
269 break;
270 }
271 field.append( c );
272 }
273 }
274 catch ( EOFException ignore )
275 {
276
277 }
278
279 return field.toString();
280 }
281
282 private char getChar()
283 throws IOException, EOFException
284 {
285 int c = reader.read();
286 if ( c < 0 )
287 {
288 throw new EOFException();
289 }
290 offset += 1;
291 return (char) c;
292 }
293
294 private void skipComment()
295 throws IOException
296 {
297 try
298 {
299 while ( getChar() != '\n' )
300 {
301
302 }
303 }
304 catch ( EOFException ignore )
305 {
306
307 }
308 }
309 }
310 }