corrade-vassal – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | vero | 1 | /* |
2 | * |
||
3 | * Class: ImgWriterPPM |
||
4 | * |
||
5 | * Description: Image writer for unsigned 8 bit data in |
||
6 | * PPM files. |
||
7 | * |
||
8 | * |
||
9 | * |
||
10 | * COPYRIGHT: |
||
11 | * |
||
12 | * This software module was originally developed by Raphaël Grosbois and |
||
13 | * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel |
||
14 | * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David |
||
15 | * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research |
||
16 | * Centre France S.A) in the course of development of the JPEG2000 |
||
17 | * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This |
||
18 | * software module is an implementation of a part of the JPEG 2000 |
||
19 | * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio |
||
20 | * Systems AB and Canon Research Centre France S.A (collectively JJ2000 |
||
21 | * Partners) agree not to assert against ISO/IEC and users of the JPEG |
||
22 | * 2000 Standard (Users) any of their rights under the copyright, not |
||
23 | * including other intellectual property rights, for this software module |
||
24 | * with respect to the usage by ISO/IEC and Users of this software module |
||
25 | * or modifications thereof for use in hardware or software products |
||
26 | * claiming conformance to the JPEG 2000 Standard. Those intending to use |
||
27 | * this software module in hardware or software products are advised that |
||
28 | * their use may infringe existing patents. The original developers of |
||
29 | * this software module, JJ2000 Partners and ISO/IEC assume no liability |
||
30 | * for use of this software module or modifications thereof. No license |
||
31 | * or right to this software module is granted for non JPEG 2000 Standard |
||
32 | * conforming products. JJ2000 Partners have full right to use this |
||
33 | * software module for his/her own purpose, assign or donate this |
||
34 | * software module to any third party and to inhibit third parties from |
||
35 | * using this software module for non JPEG 2000 Standard conforming |
||
36 | * products. This copyright notice must be included in all copies or |
||
37 | * derivative works of this software module. |
||
38 | * |
||
39 | * Copyright (c) 1999/2000 JJ2000 Partners. |
||
40 | * */ |
||
41 | using System; |
||
42 | using CSJ2K.j2k.image; |
||
43 | using CSJ2K.j2k.io; |
||
44 | using CSJ2K.j2k; |
||
45 | namespace CSJ2K.j2k.image.input |
||
46 | { |
||
47 | |||
48 | /// <summary> This class implements the ImgData interface for reading 8 bits unsigned |
||
49 | /// data from a binary PPM file |
||
50 | /// |
||
51 | /// <P> After being read the coefficients are level shifted by subtracting |
||
52 | /// 2^(nominal bit range - 1) |
||
53 | /// |
||
54 | /// <P>The transfer type (see ImgData) of this class is TYPE_INT. |
||
55 | /// |
||
56 | /// <P>This class is <i>buffered</i>: the 3 input components(R,G,B) are read |
||
57 | /// when the first one (R) is asked. The 2 others are stored until they are |
||
58 | /// needed. |
||
59 | /// |
||
60 | /// <P>NOTE: This class is not thread safe, for reasons of internal buffering. |
||
61 | /// |
||
62 | /// </summary> |
||
63 | /// <seealso cref="jj2000.j2k.image.ImgData"> |
||
64 | /// |
||
65 | /// </seealso> |
||
66 | public class ImgReaderPPM:ImgReader |
||
67 | { |
||
68 | |||
69 | /// <summary>DC offset value used when reading image </summary> |
||
70 | public static int DC_OFFSET = 128; |
||
71 | |||
72 | /// <summary>Where to read the data from </summary> |
||
73 | //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" |
||
74 | private System.IO.FileStream in_Renamed; |
||
75 | |||
76 | /// <summary>The offset of the raw pixel data in the PPM file </summary> |
||
77 | private int offset; |
||
78 | |||
79 | /// <summary>The number of bits that determine the nominal dynamic range </summary> |
||
80 | private int rb; |
||
81 | |||
82 | /// <summary>Buffer for the 3 components of each pixel(in the current block) </summary> |
||
83 | private int[][] barr = new int[3][]; |
||
84 | |||
85 | /// <summary>Data block used only to store coordinates of the buffered blocks </summary> |
||
86 | private DataBlkInt dbi = new DataBlkInt(); |
||
87 | |||
88 | /// <summary>The line buffer. </summary> |
||
89 | // This makes the class not thread safe (but it is not the only one making |
||
90 | // it so) |
||
91 | private byte[] buf; |
||
92 | |||
93 | /// <summary>Temporary DataBlkInt object (needed when encoder uses floating-point |
||
94 | /// filters). This avoid allocating new DataBlk at each time |
||
95 | /// </summary> |
||
96 | private DataBlkInt intBlk; |
||
97 | |||
98 | /// <summary> Creates a new PPM file reader from the specified file. |
||
99 | /// |
||
100 | /// </summary> |
||
101 | /// <param name="file">The input file. |
||
102 | /// |
||
103 | /// </param> |
||
104 | /// <param name="IOException">If an error occurs while opening the file. |
||
105 | /// |
||
106 | /// </param> |
||
107 | public ImgReaderPPM(System.IO.FileInfo file):this(SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(file, "r")) |
||
108 | { |
||
109 | } |
||
110 | |||
111 | /// <summary> Creates a new PPM file reader from the specified file name. |
||
112 | /// |
||
113 | /// </summary> |
||
114 | /// <param name="fname">The input file name. |
||
115 | /// |
||
116 | /// </param> |
||
117 | /// <param name="IOException">If an error occurs while opening the file. |
||
118 | /// |
||
119 | /// </param> |
||
120 | public ImgReaderPPM(System.String fname):this(SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(fname, "r")) |
||
121 | { |
||
122 | } |
||
123 | |||
124 | /// <summary> Creates a new PPM file reader from the specified RandomAccessFile |
||
125 | /// object. The file header is read to acquire the image size. |
||
126 | /// |
||
127 | /// </summary> |
||
128 | /// <param name="in">From where to read the data |
||
129 | /// |
||
130 | /// </param> |
||
131 | /// <exception cref="EOFException">if an EOF is read |
||
132 | /// </exception> |
||
133 | /// <exception cref="IOException">if an error occurs when opening the file |
||
134 | /// |
||
135 | /// </exception> |
||
136 | //UPGRADE_TODO: Class 'java.io.RandomAccessFile' was converted to 'System.IO.FileStream' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javaioRandomAccessFile'" |
||
137 | private ImgReaderPPM(System.IO.FileStream in_Renamed) |
||
138 | { |
||
139 | this.in_Renamed = in_Renamed; |
||
140 | |||
141 | confirmFileType(); |
||
142 | skipCommentAndWhiteSpace(); |
||
143 | w = readHeaderInt(); |
||
144 | skipCommentAndWhiteSpace(); |
||
145 | h = readHeaderInt(); |
||
146 | skipCommentAndWhiteSpace(); |
||
147 | /*Read the highest pixel value from header (not used)*/ |
||
148 | readHeaderInt(); |
||
149 | nc = 3; |
||
150 | rb = 8; |
||
151 | } |
||
152 | |||
153 | /// <summary> Closes the underlying file from where the image data is being read. No |
||
154 | /// operations are possible after a call to this method. |
||
155 | /// |
||
156 | /// </summary> |
||
157 | /// <exception cref="IOException">If an I/O error occurs. |
||
158 | /// |
||
159 | /// </exception> |
||
160 | public override void close() |
||
161 | { |
||
162 | in_Renamed.Close(); |
||
163 | in_Renamed = null; |
||
164 | // Free memory |
||
165 | barr[0] = null; |
||
166 | barr[1] = null; |
||
167 | barr[2] = null; |
||
168 | buf = null; |
||
169 | } |
||
170 | |||
171 | |||
172 | /// <summary> Returns the number of bits corresponding to the nominal range of the |
||
173 | /// data in the specified component. This is the value rb (range bits) that |
||
174 | /// was specified in the constructor, which normally is 8 for non bilevel |
||
175 | /// data, and 1 for bilevel data. |
||
176 | /// |
||
177 | /// <P>If this number is <i>b</b> then the nominal range is between |
||
178 | /// -2^(b-1) and 2^(b-1)-1, since unsigned data is level shifted to have a |
||
179 | /// nominal avergae of 0. |
||
180 | /// |
||
181 | /// </summary> |
||
182 | /// <param name="c">The index of the component. |
||
183 | /// |
||
184 | /// </param> |
||
185 | /// <returns> The number of bits corresponding to the nominal range of the |
||
186 | /// data. For floating-point data this value is not applicable and the |
||
187 | /// return value is undefined. |
||
188 | /// |
||
189 | /// </returns> |
||
190 | public override int getNomRangeBits(int c) |
||
191 | { |
||
192 | // Check component index |
||
193 | if (c < 0 || c > 2) |
||
194 | throw new System.ArgumentException(); |
||
195 | |||
196 | return rb; |
||
197 | } |
||
198 | |||
199 | /// <summary> Returns the position of the fixed point in the specified component |
||
200 | /// (i.e. the number of fractional bits), which is always 0 for this |
||
201 | /// ImgReader. |
||
202 | /// |
||
203 | /// </summary> |
||
204 | /// <param name="c">The index of the component. |
||
205 | /// |
||
206 | /// </param> |
||
207 | /// <returns> The position of the fixed-point (i.e. the number of fractional |
||
208 | /// bits). Always 0 for this ImgReader. |
||
209 | /// |
||
210 | /// </returns> |
||
211 | public override int getFixedPoint(int c) |
||
212 | { |
||
213 | // Check component index |
||
214 | if (c < 0 || c > 2) |
||
215 | throw new System.ArgumentException(); |
||
216 | return 0; |
||
217 | } |
||
218 | |||
219 | |||
220 | /// <summary> Returns, in the blk argument, the block of image data containing the |
||
221 | /// specifed rectangular area, in the specified component. The data is |
||
222 | /// returned, as a reference to the internal data, if any, instead of as a |
||
223 | /// copy, therefore the returned data should not be modified. |
||
224 | /// |
||
225 | /// <P> After being read the coefficients are level shifted by subtracting |
||
226 | /// 2^(nominal bit range - 1) |
||
227 | /// |
||
228 | /// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w' |
||
229 | /// and 'h' members of the 'blk' argument, relative to the current |
||
230 | /// tile. These members are not modified by this method. The 'offset' and |
||
231 | /// 'scanw' of the returned data can be arbitrary. See the 'DataBlk' class. |
||
232 | /// |
||
233 | /// <P>If the data array in <tt>blk</tt> is <tt>null</tt>, then a new one |
||
234 | /// is created if necessary. The implementation of this interface may |
||
235 | /// choose to return the same array or a new one, depending on what is more |
||
236 | /// efficient. Therefore, the data array in <tt>blk</tt> prior to the |
||
237 | /// method call should not be considered to contain the returned data, a |
||
238 | /// new array may have been created. Instead, get the array from |
||
239 | /// <tt>blk</tt> after the method has returned. |
||
240 | /// |
||
241 | /// <P>The returned data always has its 'progressive' attribute unset |
||
242 | /// (i.e. false). |
||
243 | /// |
||
244 | /// <P>When an I/O exception is encountered the JJ2KExceptionHandler is |
||
245 | /// used. The exception is passed to its handleException method. The action |
||
246 | /// that is taken depends on the action that has been registered in |
||
247 | /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details. |
||
248 | /// |
||
249 | /// <P>This method implements buffering for the 3 components: When the |
||
250 | /// first one is asked, all the 3 components are read and stored until they |
||
251 | /// are needed. |
||
252 | /// |
||
253 | /// </summary> |
||
254 | /// <param name="blk">Its coordinates and dimensions specify the area to |
||
255 | /// return. Some fields in this object are modified to return the data. |
||
256 | /// |
||
257 | /// </param> |
||
258 | /// <param name="c">The index of the component from which to get the data. Only 0, |
||
259 | /// 1 and 3 are valid. |
||
260 | /// |
||
261 | /// </param> |
||
262 | /// <returns> The requested DataBlk |
||
263 | /// |
||
264 | /// </returns> |
||
265 | /// <seealso cref="getCompData"> |
||
266 | /// |
||
267 | /// </seealso> |
||
268 | /// <seealso cref="JJ2KExceptionHandler"> |
||
269 | /// |
||
270 | /// </seealso> |
||
271 | public override DataBlk getInternCompData(DataBlk blk, int c) |
||
272 | { |
||
273 | // Check component index |
||
274 | if (c < 0 || c > 2) |
||
275 | throw new System.ArgumentException(); |
||
276 | |||
277 | // Check type of block provided as an argument |
||
278 | if (blk.DataType != DataBlk.TYPE_INT) |
||
279 | { |
||
280 | if (intBlk == null) |
||
281 | intBlk = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h); |
||
282 | else |
||
283 | { |
||
284 | intBlk.ulx = blk.ulx; |
||
285 | intBlk.uly = blk.uly; |
||
286 | intBlk.w = blk.w; |
||
287 | intBlk.h = blk.h; |
||
288 | } |
||
289 | blk = intBlk; |
||
290 | } |
||
291 | |||
292 | // If asking a component for the first time for this block, read the 3 |
||
293 | // components |
||
294 | if ((barr[c] == null) || (dbi.ulx > blk.ulx) || (dbi.uly > blk.uly) || (dbi.ulx + dbi.w < blk.ulx + blk.w) || (dbi.uly + dbi.h < blk.uly + blk.h)) |
||
295 | { |
||
296 | int k, j, i, mi; |
||
297 | int[] red, green, blue; |
||
298 | |||
299 | // Reset data arrays if needed |
||
300 | if (barr[c] == null || barr[c].Length < blk.w * blk.h) |
||
301 | { |
||
302 | barr[c] = new int[blk.w * blk.h]; |
||
303 | } |
||
304 | blk.Data = barr[c]; |
||
305 | |||
306 | i = (c + 1) % 3; |
||
307 | if (barr[i] == null || barr[i].Length < blk.w * blk.h) |
||
308 | { |
||
309 | barr[i] = new int[blk.w * blk.h]; |
||
310 | } |
||
311 | i = (c + 2) % 3; |
||
312 | if (barr[i] == null || barr[i].Length < blk.w * blk.h) |
||
313 | { |
||
314 | barr[i] = new int[blk.w * blk.h]; |
||
315 | } |
||
316 | |||
317 | // set attributes of the DataBlk used for buffering |
||
318 | dbi.ulx = blk.ulx; |
||
319 | dbi.uly = blk.uly; |
||
320 | dbi.w = blk.w; |
||
321 | dbi.h = blk.h; |
||
322 | |||
323 | // Check line buffer |
||
324 | if (buf == null || buf.Length < 3 * blk.w) |
||
325 | { |
||
326 | buf = new byte[3 * blk.w]; |
||
327 | } |
||
328 | |||
329 | red = barr[0]; |
||
330 | green = barr[1]; |
||
331 | blue = barr[2]; |
||
332 | |||
333 | try |
||
334 | { |
||
335 | // Read line by line |
||
336 | mi = blk.uly + blk.h; |
||
337 | for (i = blk.uly; i < mi; i++) |
||
338 | { |
||
339 | // Reposition in input offset takes care of |
||
340 | // header offset |
||
341 | in_Renamed.Seek(offset + i * 3 * w + 3 * blk.ulx, System.IO.SeekOrigin.Begin); |
||
342 | in_Renamed.Read(buf, 0, 3 * blk.w); |
||
343 | |||
344 | for (k = (i - blk.uly) * blk.w + blk.w - 1, j = 3 * blk.w - 1; j >= 0; k--) |
||
345 | { |
||
346 | // Read every third sample |
||
347 | blue[k] = (((byte) buf[j--]) & 0xFF) - DC_OFFSET; |
||
348 | green[k] = (((byte) buf[j--]) & 0xFF) - DC_OFFSET; |
||
349 | red[k] = (((byte) buf[j--]) & 0xFF) - DC_OFFSET; |
||
350 | } |
||
351 | } |
||
352 | } |
||
353 | catch (System.IO.IOException e) |
||
354 | { |
||
355 | JJ2KExceptionHandler.handleException(e); |
||
356 | } |
||
357 | barr[0] = red; |
||
358 | barr[1] = green; |
||
359 | barr[2] = blue; |
||
360 | |||
361 | // Set buffer attributes |
||
362 | blk.Data = barr[c]; |
||
363 | blk.offset = 0; |
||
364 | blk.scanw = blk.w; |
||
365 | } |
||
366 | else |
||
367 | { |
||
368 | //Asking for the 2nd or 3rd block component |
||
369 | blk.Data = barr[c]; |
||
370 | blk.offset = (blk.ulx - dbi.ulx) * dbi.w + blk.ulx - dbi.ulx; |
||
371 | blk.scanw = dbi.scanw; |
||
372 | } |
||
373 | |||
374 | // Turn off the progressive attribute |
||
375 | blk.progressive = false; |
||
376 | return blk; |
||
377 | } |
||
378 | |||
379 | /// <summary> Returns, in the blk argument, a block of image data containing the |
||
380 | /// specifed rectangular area, in the specified component. The data is |
||
381 | /// returned, as a copy of the internal data, therefore the returned data |
||
382 | /// can be modified "in place". |
||
383 | /// |
||
384 | /// <P> After being read the coefficients are level shifted by subtracting |
||
385 | /// 2^(nominal bit range - 1) |
||
386 | /// |
||
387 | /// <P>The rectangular area to return is specified by the 'ulx', 'uly', 'w' |
||
388 | /// and 'h' members of the 'blk' argument, relative to the current |
||
389 | /// tile. These members are not modified by this method. The 'offset' of |
||
390 | /// the returned data is 0, and the 'scanw' is the same as the block's |
||
391 | /// width. See the 'DataBlk' class. |
||
392 | /// |
||
393 | /// <P>If the data array in 'blk' is 'null', then a new one is created. If |
||
394 | /// the data array is not 'null' then it is reused, and it must be large |
||
395 | /// enough to contain the block's data. Otherwise an 'ArrayStoreException' |
||
396 | /// or an 'IndexOutOfBoundsException' is thrown by the Java system. |
||
397 | /// |
||
398 | /// <P>The returned data has its 'progressive' attribute unset |
||
399 | /// (i.e. false). |
||
400 | /// |
||
401 | /// <P>When an I/O exception is encountered the JJ2KExceptionHandler is |
||
402 | /// used. The exception is passed to its handleException method. The action |
||
403 | /// that is taken depends on the action that has been registered in |
||
404 | /// JJ2KExceptionHandler. See JJ2KExceptionHandler for details. |
||
405 | /// |
||
406 | /// </summary> |
||
407 | /// <param name="blk">Its coordinates and dimensions specify the area to |
||
408 | /// return. If it contains a non-null data array, then it must have the |
||
409 | /// correct dimensions. If it contains a null data array a new one is |
||
410 | /// created. The fields in this object are modified to return the data. |
||
411 | /// |
||
412 | /// </param> |
||
413 | /// <param name="c">The index of the component from which to get the data. Only |
||
414 | /// 0,1 and 2 are valid. |
||
415 | /// |
||
416 | /// </param> |
||
417 | /// <returns> The requested DataBlk |
||
418 | /// |
||
419 | /// </returns> |
||
420 | /// <seealso cref="getInternCompData"> |
||
421 | /// |
||
422 | /// </seealso> |
||
423 | /// <seealso cref="JJ2KExceptionHandler"> |
||
424 | /// |
||
425 | /// </seealso> |
||
426 | public override DataBlk getCompData(DataBlk blk, int c) |
||
427 | { |
||
428 | // NOTE: can not directly call getInterCompData since that returns |
||
429 | // internally buffered data. |
||
430 | int ulx, uly, w, h; |
||
431 | |||
432 | // Check type of block provided as an argument |
||
433 | if (blk.DataType != DataBlk.TYPE_INT) |
||
434 | { |
||
435 | DataBlkInt tmp = new DataBlkInt(blk.ulx, blk.uly, blk.w, blk.h); |
||
436 | blk = tmp; |
||
437 | } |
||
438 | |||
439 | int[] bakarr = (int[]) blk.Data; |
||
440 | // Save requested block size |
||
441 | ulx = blk.ulx; |
||
442 | uly = blk.uly; |
||
443 | w = blk.w; |
||
444 | h = blk.h; |
||
445 | // Force internal data buffer to be different from external |
||
446 | blk.Data = null; |
||
447 | getInternCompData(blk, c); |
||
448 | // Copy the data |
||
449 | if (bakarr == null) |
||
450 | { |
||
451 | bakarr = new int[w * h]; |
||
452 | } |
||
453 | if (blk.offset == 0 && blk.scanw == w) |
||
454 | { |
||
455 | // Requested and returned block buffer are the same size |
||
456 | // CONVERSION PROBLEM? |
||
457 | Array.Copy((System.Array)blk.Data, 0, (System.Array)bakarr, 0, w * h); |
||
458 | } |
||
459 | else |
||
460 | { |
||
461 | // Requested and returned block are different |
||
462 | for (int i = h - 1; i >= 0; i--) |
||
463 | { |
||
464 | // copy line by line |
||
465 | // CONVERSION PROBLEM? |
||
466 | Array.Copy((System.Array)blk.Data, blk.offset + i * blk.scanw, (System.Array)bakarr, i * w, w); |
||
467 | } |
||
468 | } |
||
469 | blk.Data = bakarr; |
||
470 | blk.offset = 0; |
||
471 | blk.scanw = blk.w; |
||
472 | return blk; |
||
473 | } |
||
474 | |||
475 | /// <summary> Returns a byte read from the RandomAccessFile. The number of read byted |
||
476 | /// are counted to keep track of the offset of the pixel data in the PPM |
||
477 | /// file |
||
478 | /// |
||
479 | /// </summary> |
||
480 | /// <returns> One byte read from the header of the PPM file. |
||
481 | /// |
||
482 | /// </returns> |
||
483 | private byte countedByteRead() |
||
484 | { |
||
485 | offset++; |
||
486 | return (byte) in_Renamed.ReadByte(); |
||
487 | } |
||
488 | |||
489 | /// <summary> Checks that the file begins with 'P6' |
||
490 | /// |
||
491 | /// </summary> |
||
492 | private void confirmFileType() |
||
493 | { |
||
494 | byte[] type = new byte[]{80, 54}; |
||
495 | int i; |
||
496 | byte b; |
||
497 | |||
498 | for (i = 0; i < 2; i++) |
||
499 | { |
||
500 | b = countedByteRead(); |
||
501 | if (b != type[i]) |
||
502 | { |
||
503 | if (i == 1 && b == 51) |
||
504 | { |
||
505 | // i.e 'P3' |
||
506 | throw new System.ArgumentException("JJ2000 does not support" + " ascii-PPM files. Use " + " raw-PPM file instead. "); |
||
507 | } |
||
508 | else |
||
509 | { |
||
510 | throw new System.ArgumentException("Not a raw-PPM file"); |
||
511 | } |
||
512 | } |
||
513 | } |
||
514 | } |
||
515 | |||
516 | /// <summary> Skips any line in the header starting with '#' and any space, tab, line |
||
517 | /// feed or carriage return. |
||
518 | /// |
||
519 | /// </summary> |
||
520 | private void skipCommentAndWhiteSpace() |
||
521 | { |
||
522 | |||
523 | bool done = false; |
||
524 | byte b; |
||
525 | |||
526 | while (!done) |
||
527 | { |
||
528 | b = countedByteRead(); |
||
529 | if (b == 35) |
||
530 | { |
||
531 | // Comment start |
||
532 | while (b != 10 && b != 13) |
||
533 | { |
||
534 | // While not comment end (end-of-line) |
||
535 | b = countedByteRead(); |
||
536 | } |
||
537 | } |
||
538 | else if (!(b == 9 || b == 10 || b == 13 || b == 32)) |
||
539 | { |
||
540 | // If not whitespace |
||
541 | done = true; |
||
542 | } |
||
543 | } |
||
544 | // Put back last valid byte |
||
545 | offset--; |
||
546 | in_Renamed.Seek(offset, System.IO.SeekOrigin.Begin); |
||
547 | } |
||
548 | |||
549 | /// <summary> Returns an int read from the header of the PPM file. |
||
550 | /// |
||
551 | /// </summary> |
||
552 | /// <returns> One int read from the header of the PPM file. |
||
553 | /// |
||
554 | /// </returns> |
||
555 | private int readHeaderInt() |
||
556 | { |
||
557 | int res = 0; |
||
558 | byte b = 0; |
||
559 | |||
560 | b = countedByteRead(); |
||
561 | while (b != 32 && b != 10 && b != 9 && b != 13) |
||
562 | { |
||
563 | // While not whitespace |
||
564 | res = res * 10 + b - 48; // Convert from ASCII to decimal |
||
565 | b = countedByteRead(); |
||
566 | } |
||
567 | return res; |
||
568 | } |
||
569 | |||
570 | /// <summary> Returns true if the data read was originally signed in the specified |
||
571 | /// component, false if not. This method always returns false since PPM |
||
572 | /// data is always unsigned. |
||
573 | /// |
||
574 | /// </summary> |
||
575 | /// <param name="c">The index of the component, from 0 to N-1. |
||
576 | /// |
||
577 | /// </param> |
||
578 | /// <returns> always false, since PPM data is always unsigned. |
||
579 | /// |
||
580 | /// </returns> |
||
581 | public override bool isOrigSigned(int c) |
||
582 | { |
||
583 | // Check component index |
||
584 | if (c < 0 || c > 2) |
||
585 | throw new System.ArgumentException(); |
||
586 | return false; |
||
587 | } |
||
588 | |||
589 | /// <summary> Returns a string of information about the object, more than 1 line |
||
590 | /// long. The information string includes information from the underlying |
||
591 | /// RandomAccessFile (its toString() method is called in turn). |
||
592 | /// |
||
593 | /// </summary> |
||
594 | /// <returns> A string of information about the object. |
||
595 | /// |
||
596 | /// </returns> |
||
597 | public override System.String ToString() |
||
598 | { |
||
599 | //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Object.toString' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'" |
||
600 | return "ImgReaderPPM: WxH = " + w + "x" + h + ", Component = 0,1,2" + "\nUnderlying RandomAccessFile:\n" + in_Renamed.ToString(); |
||
601 | } |
||
602 | } |
||
603 | } |