corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * CVS identifier:
3 *
4 * $Id: ImgWriterPGM.java,v 1.14 2002/07/19 14:13:38 grosbois Exp $
5 *
6 * Class: ImgWriterRawPGM
7 *
8 * Description: Image writer for unsigned 8 bit data in
9 * PGM file format.
10 *
11 *
12 *
13 * COPYRIGHT:
14 *
15 * This software module was originally developed by Raphaël Grosbois and
16 * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
17 * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
18 * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
19 * Centre France S.A) in the course of development of the JPEG2000
20 * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
21 * software module is an implementation of a part of the JPEG 2000
22 * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
23 * Systems AB and Canon Research Centre France S.A (collectively JJ2000
24 * Partners) agree not to assert against ISO/IEC and users of the JPEG
25 * 2000 Standard (Users) any of their rights under the copyright, not
26 * including other intellectual property rights, for this software module
27 * with respect to the usage by ISO/IEC and Users of this software module
28 * or modifications thereof for use in hardware or software products
29 * claiming conformance to the JPEG 2000 Standard. Those intending to use
30 * this software module in hardware or software products are advised that
31 * their use may infringe existing patents. The original developers of
32 * this software module, JJ2000 Partners and ISO/IEC assume no liability
33 * for use of this software module or modifications thereof. No license
34 * or right to this software module is granted for non JPEG 2000 Standard
35 * conforming products. JJ2000 Partners have full right to use this
36 * software module for his/her own purpose, assign or donate this
37 * software module to any third party and to inhibit third parties from
38 * using this software module for non JPEG 2000 Standard conforming
39 * products. This copyright notice must be included in all copies or
40 * derivative works of this software module.
41 *
42 * Copyright (c) 1999/2000 JJ2000 Partners.
43 * */
44 using System;
45 using CSJ2K.j2k.image;
46 using CSJ2K.j2k.util;
47 namespace CSJ2K.j2k.image.output
48 {
49  
50 /// <summary> This class writes a component from an image in 8 bit unsigned data to a
51 /// binary PGM file. The size of the image that is written to the file is the
52 /// size of the component from which to get the data, not the size of the
53 /// source image (they differ if there is some sub-sampling).
54 ///
55 /// <p>Before writing, all coefficients are inversly level shifted and then
56 /// "saturated" (they are limited to the nominal dynamic range).<br> <u>Ex:</u>
57 /// if the nominal range is 0-255, the following algorithm is applied:<br>
58 /// <tt>if coeff<0, output=0<br> if coeff>255, output=255<br> else
59 /// output=coeff</tt></p>
60 ///
61 /// <p>The write() methods of an object of this class may not be called
62 /// concurrently from different threads.</p>
63 ///
64 /// <p>NOTE: This class is not thread safe, for reasons of internal
65 /// buffering.</p>
66 ///
67 /// </summary>
68 public class ImgWriterPGM:ImgWriter
69 {
70  
71 /// <summary>Value used to inverse level shift </summary>
72 private int levShift;
73  
74 /// <summary>Where to write the data </summary>
75 //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'"
76 private System.IO.FileStream out_Renamed;
77  
78 /// <summary>The index of the component from where to get the data </summary>
79 private int c;
80  
81 /// <summary>The number of fractional bits in the source data </summary>
82 private int fb;
83  
84 /// <summary>A DataBlk, just used to avoid allocating a new one each time
85 /// it is needed
86 /// </summary>
87 private DataBlkInt db = new DataBlkInt();
88  
89 /// <summary>The offset of the raw pixel data in the PGM file </summary>
90 private int offset;
91  
92 /// <summary>The line buffer. </summary>
93 // This makes the class not thrad safe
94 // (but it is not the only one making it so)
95 private byte[] buf;
96  
97 /// <summary> Creates a new writer to the specified File object, to write data from
98 /// the specified component.
99 ///
100 /// <p>The size of the image that is written to the file is the size of the
101 /// component from which to get the data, specified by b, not the size of
102 /// the source image (they differ if there is some sub-sampling).</p>
103 ///
104 /// </summary>
105 /// <param name="out">The file where to write the data
106 ///
107 /// </param>
108 /// <param name="imgSrc">The source from where to get the image data to write.
109 ///
110 /// </param>
111 /// <param name="c">The index of the component from where to get the data.
112 ///
113 /// </param>
114 public ImgWriterPGM(System.IO.FileInfo out_Renamed, BlkImgDataSrc imgSrc, int c)
115 {
116 // Check that imgSrc is of the correct type
117 // Check that the component index is valid
118 if (c < 0 || c >= imgSrc.NumComps)
119 {
120 throw new System.ArgumentException("Invalid number of components");
121 }
122  
123 // Check that imgSrc is of the correct type
124 if (imgSrc.getNomRangeBits(c) > 8)
125 {
126 FacilityManager.getMsgLogger().println("Warning: Component " + c + " has nominal bitdepth " + imgSrc.getNomRangeBits(c) + ". Pixel values will be " + "down-shifted to fit bitdepth of 8 for PGM file", 8, 8);
127 }
128  
129 // Initialize
130 bool tmpBool;
131 if (System.IO.File.Exists(out_Renamed.FullName))
132 tmpBool = true;
133 else
134 tmpBool = System.IO.Directory.Exists(out_Renamed.FullName);
135 bool tmpBool2;
136 if (System.IO.File.Exists(out_Renamed.FullName))
137 {
138 System.IO.File.Delete(out_Renamed.FullName);
139 tmpBool2 = true;
140 }
141 else if (System.IO.Directory.Exists(out_Renamed.FullName))
142 {
143 System.IO.Directory.Delete(out_Renamed.FullName);
144 tmpBool2 = true;
145 }
146 else
147 tmpBool2 = false;
148 if (tmpBool && !tmpBool2)
149 {
150 throw new System.IO.IOException("Could not reset file");
151 }
152 this.out_Renamed = SupportClass.RandomAccessFileSupport.CreateRandomAccessFile(out_Renamed, "rw");
153 src = imgSrc;
154 this.c = c;
155 w = imgSrc.ImgWidth;
156 h = imgSrc.ImgHeight;
157 fb = imgSrc.getFixedPoint(c);
158 levShift = 1 << (imgSrc.getNomRangeBits(c) - 1);
159  
160 writeHeaderInfo();
161 }
162  
163 /// <summary> Creates a new writer to the specified file, to write data from the
164 /// specified component.
165 ///
166 /// <P>The size of the image that is written to the file is the size of the
167 /// component from which to get the data, specified by b, not the size of
168 /// the source image (they differ if there is some sub-sampling).
169 ///
170 /// </summary>
171 /// <param name="fname">The name of the file where to write the data
172 ///
173 /// </param>
174 /// <param name="imgSrc">The source from where to get the image data to write.
175 ///
176 /// </param>
177 /// <param name="c">The index of the component from where to get the data.
178 ///
179 /// </param>
180 public ImgWriterPGM(System.String fname, BlkImgDataSrc imgSrc, int c):this(new System.IO.FileInfo(fname), imgSrc, c)
181 {
182 }
183  
184 /// <summary> Closes the underlying file or netwrok connection to where the data is
185 /// written. Any call to other methods of the class become illegal after a
186 /// call to this one.
187 ///
188 /// </summary>
189 /// <exception cref="IOException">If an I/O error occurs.
190 ///
191 /// </exception>
192 public override void close()
193 {
194 int i;
195 // Finish writing the file, writing 0s at the end if the data at end
196 // has not been written.
197 if (out_Renamed.Length != w * h + offset)
198 {
199 // Goto end of file
200 out_Renamed.Seek(out_Renamed.Length, System.IO.SeekOrigin.Begin);
201 // Fill with 0s
202 for (i = offset + w * h - (int) out_Renamed.Length; i > 0; i--)
203 {
204 out_Renamed.WriteByte((System.Byte) 0);
205 }
206 }
207 out_Renamed.Close();
208 src = null;
209 out_Renamed = null;
210 db = null;
211 }
212  
213 /// <summary> Writes all buffered data to the file or resource.
214 ///
215 /// </summary>
216 /// <exception cref="IOException">If an I/O error occurs.
217 ///
218 /// </exception>
219 public override void flush()
220 {
221 // No flush needed here since we are using a RandomAccessFile Get rid
222 // of line buffer (is this a good choice?)
223 buf = null;
224 }
225  
226 /// <summary> Writes the data of the specified area to the file, coordinates are
227 /// relative to the current tile of the source. Before writing, the
228 /// coefficients are limited to the nominal range.
229 ///
230 /// <p>This method may not be called concurrently from different
231 /// threads.</p>
232 ///
233 /// <p>If the data returned from the BlkImgDataSrc source is progressive,
234 /// then it is requested over and over until it is not progressive
235 /// anymore.</p>
236 ///
237 /// </summary>
238 /// <param name="ulx">The horizontal coordinate of the upper-left corner of the
239 /// area to write, relative to the current tile.
240 ///
241 /// </param>
242 /// <param name="uly">The vertical coordinate of the upper-left corner of the area
243 /// to write, relative to the current tile.
244 ///
245 /// </param>
246 /// <param name="width">The width of the area to write.
247 ///
248 /// </param>
249 /// <param name="height">The height of the area to write.
250 ///
251 /// </param>
252 /// <exception cref="IOException">If an I/O error occurs.
253 ///
254 /// </exception>
255 public override void write(int ulx, int uly, int w, int h)
256 {
257 int k, i, j;
258 int fracbits = fb; // In local variable for faster access
259 int tOffx, tOffy; // Active tile offset in the X and Y direction
260  
261 // Initialize db
262 db.ulx = ulx;
263 db.uly = uly;
264 db.w = w;
265 db.h = h;
266 // Get the current active tile offset
267 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
268 tOffx = src.getCompULX(c) - (int) System.Math.Ceiling(src.ImgULX / (double) src.getCompSubsX(c));
269 //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
270 tOffy = src.getCompULY(c) - (int) System.Math.Ceiling(src.ImgULY / (double) src.getCompSubsY(c));
271 // Check the array size
272 if (db.data_array != null && db.data_array.Length < w * h)
273 {
274 // A new one will be allocated by getInternCompData()
275 db.data_array = null;
276 }
277 // Request the data and make sure it is not
278 // progressive
279 do
280 {
281 db = (DataBlkInt) src.getInternCompData(db, c);
282 }
283 while (db.progressive);
284  
285 // variables used during coeff saturation
286 int tmp, maxVal = (1 << src.getNomRangeBits(c)) - 1;
287  
288 // If nominal bitdepth greater than 8, calculate down shift
289 int downShift = src.getNomRangeBits(c) - 8;
290 if (downShift < 0)
291 {
292 downShift = 0;
293 }
294  
295 // Check line buffer
296 if (buf == null || buf.Length < w)
297 {
298 buf = new byte[w]; // Expand buffer
299 }
300  
301 // Write line by line
302 for (i = 0; i < h; i++)
303 {
304 // Skip to beggining of line in file
305 out_Renamed.Seek(this.offset + this.w * (uly + tOffy + i) + ulx + tOffx, System.IO.SeekOrigin.Begin);
306 // Write all bytes in the line
307 if (fracbits == 0)
308 {
309 for (k = db.offset + i * db.scanw + w - 1, j = w - 1; j >= 0; j--, k--)
310 {
311 tmp = db.data_array[k] + levShift;
312 buf[j] = (byte) (((tmp < 0)?0:((tmp > maxVal)?maxVal:tmp)) >> downShift);
313 }
314 }
315 else
316 {
317 for (k = db.offset + i * db.scanw + w - 1, j = w - 1; j >= 0; j--, k--)
318 {
319 tmp = (db.data_array[k] >> fracbits) + levShift;
320 buf[j] = (byte) (((tmp < 0)?0:((tmp > maxVal)?maxVal:tmp)) >> downShift);
321 }
322 }
323 out_Renamed.Write(buf, 0, w);
324 }
325 }
326  
327 /// <summary> Writes the source's current tile to the output. The requests of data
328 /// issued to the source BlkImgDataSrc object are done by strips, in order
329 /// to reduce memory usage.
330 ///
331 /// <p>If the data returned from the BlkImgDataSrc source is progressive,
332 /// then it is requested over and over until it is not progressive
333 /// anymore.</p>
334 ///
335 /// </summary>
336 /// <exception cref="IOException">If an I/O error occurs.
337 ///
338 /// </exception>
339 /// <seealso cref="DataBlk">
340 ///
341 /// </seealso>
342 public override void write()
343 {
344 int i;
345 int tIdx = src.TileIdx;
346 int tw = src.getTileCompWidth(tIdx, c); // Tile width
347 int th = src.getTileCompHeight(tIdx, c); // Tile height
348 // Write in strips
349 for (i = 0; i < th; i += DEF_STRIP_HEIGHT)
350 {
351 write(0, i, tw, (th - i < DEF_STRIP_HEIGHT)?th - i:DEF_STRIP_HEIGHT);
352 }
353 }
354  
355 /// <summary> Writes the header info of the PGM file :
356 ///
357 /// P5
358 /// width height
359 /// 255
360 ///
361 /// </summary>
362 /// <exception cref="IOException">If there is an IOException
363 ///
364 /// </exception>
365 private void writeHeaderInfo()
366 {
367 byte[] byteVals;
368 int i;
369 System.String val;
370  
371 // write 'P5' to file
372 out_Renamed.WriteByte((System.Byte) 'P'); // 'P'
373 out_Renamed.WriteByte((System.Byte) '5'); // '5'
374 out_Renamed.WriteByte((System.Byte) '\n'); // newline
375 offset = 3;
376 // Write width in ASCII
377 val = System.Convert.ToString(w);
378 byteVals = System.Text.ASCIIEncoding.ASCII.GetBytes(val);
379 for (i = 0; i < byteVals.Length; i++)
380 {
381 out_Renamed.WriteByte((byte) byteVals[i]);
382 offset++;
383 }
384 out_Renamed.WriteByte((System.Byte) ' '); // blank
385 offset++;
386 // Write height in ASCII
387 val = System.Convert.ToString(h);
388 byteVals = System.Text.ASCIIEncoding.ASCII.GetBytes(val);
389 for (i = 0; i < byteVals.Length; i++)
390 {
391 out_Renamed.WriteByte((byte) byteVals[i]);
392 offset++;
393 }
394 // Write maxval
395 out_Renamed.WriteByte((System.Byte) '\n'); // newline
396 out_Renamed.WriteByte((System.Byte) '2'); // '2'
397 out_Renamed.WriteByte((System.Byte) '5'); // '5'
398 out_Renamed.WriteByte((System.Byte) '5'); // '5'
399 out_Renamed.WriteByte((System.Byte) '\n'); // newline
400 offset += 5;
401 }
402  
403 /// <summary> Returns a string of information about the object, more than 1 line
404 /// long. The information string includes information from the underlying
405 /// RandomAccessFile (its toString() method is called in turn).
406 ///
407 /// </summary>
408 /// <returns> A string of information about the object.
409 ///
410 /// </returns>
411 public override System.String ToString()
412 {
413 //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'"
414 return "ImgWriterPGM: WxH = " + w + "x" + h + ", Component=" + c + "\nUnderlying RandomAccessFile:\n" + out_Renamed.ToString();
415 }
416 }
417 }