[System.Net] Add support for .pac proxy config scripts on mac
[mono.git] / mcs / class / System.Drawing / System.Drawing.Imaging / ImageCodec.jvm.cs
1 using System;\r
2 using System.Configuration;\r
3 using System.Collections;\r
4 using System.Collections.Specialized;\r
5 using System.Drawing.Imaging;\r
6 using System.Xml;\r
7 using Mainsoft.Drawing.Configuration;\r
8 \r
9 using imageio = javax.imageio;\r
10 using stream = javax.imageio.stream;\r
11 using awt = java.awt;\r
12 using image = java.awt.image;\r
13 using spi = javax.imageio.spi;\r
14 using dom = org.w3c.dom;\r
15 \r
16 namespace Mainsoft.Drawing.Imaging {\r
17         /// <summary>\r
18         /// Summary description for ImageCodec.\r
19         /// </summary>\r
20         public class ImageCodec : IDisposable {\r
21 \r
22                 #region Members\r
23 \r
24                 imageio.ImageReader _nativeReader = null;\r
25                 imageio.ImageWriter _nativeWriter = null;\r
26                 stream.ImageInputStream _nativeStream = null;\r
27 \r
28                 ImageFormat _imageFormat = null;\r
29 \r
30                 int _currentFrame = 0;\r
31 \r
32                 #endregion\r
33 \r
34                 #region Constructros\r
35 \r
36                 protected ImageCodec() {\r
37                 }\r
38 \r
39                 static ImageCodec() {\r
40                 }\r
41 \r
42                 #endregion\r
43 \r
44                 #region Internal properties\r
45 \r
46                 internal imageio.ImageReader NativeReader {\r
47                         get { return _nativeReader; }\r
48                         set { \r
49                                 _nativeReader = value; \r
50                                 if (value == null)\r
51                                         return;\r
52                                 _imageFormat = MimeTypesToImageFormat( value.getOriginatingProvider().getMIMETypes() );\r
53                         }\r
54                 }\r
55                 internal imageio.ImageWriter NativeWriter {\r
56                         get { return _nativeWriter; }\r
57                         set { \r
58                                 _nativeWriter = value; \r
59                                 if (value == null)\r
60                                         return;\r
61                                 _imageFormat = MimeTypesToImageFormat( value.getOriginatingProvider().getMIMETypes() );\r
62                         }\r
63                 }\r
64 \r
65                 internal stream.ImageInputStream NativeStream {\r
66                         get { return _nativeStream; }\r
67                         set {\r
68                                 _nativeStream = value;\r
69                                 if (value == null)\r
70                                         return;\r
71 \r
72                                 if (NativeReader != null)\r
73                                         NativeReader.setInput( value );\r
74 \r
75                                 if (NativeWriter != null)\r
76                                         NativeWriter.setOutput( value );\r
77                         }\r
78                 }\r
79 \r
80                 #endregion\r
81 \r
82                 #region ImageCodec factory methods\r
83 \r
84                 public static ImageCodec CreateReader(stream.ImageInputStream inputStream) {\r
85                         java.util.Iterator iter = imageio.ImageIO.getImageReaders( inputStream );\r
86                         return CreateReader(iter);\r
87                 }\r
88 \r
89                 public static ImageCodec CreateReader(ImageFormat imageFormat) {\r
90                         return CreateReader( ImageFormatToClsid( imageFormat ) );\r
91                 }\r
92 \r
93                 public static ImageCodec CreateReader(Guid clsid) {\r
94                         ImageCodec codec = null;\r
95                         try {\r
96                                 ImageCodecInfo codecInfo = FindDecoder(clsid);\r
97                                 java.util.Iterator iter = imageio.ImageIO.getImageReadersByMIMEType( codecInfo.MimeType );\r
98                                 codec = CreateReader(iter);\r
99                         }\r
100                         catch {}\r
101 \r
102                         if (codec == null) {\r
103                                 ImageFormat format = ClsidToImageFormat(clsid);\r
104                                 string name = (format != null) ? format.ToString() : clsid.ToString();\r
105                                 throw new NotSupportedException(String.Format("The '{0}' format decoder is not installed.", name));\r
106                         }\r
107 \r
108                         return codec;\r
109                 }\r
110 \r
111                 private static ImageCodec CreateReader(java.util.Iterator iter) {\r
112                         if ( !iter.hasNext() )
113                                 return null;
114 \r
115                         ImageCodec imageCodec = new ImageCodec();\r
116                         imageCodec.NativeReader = (imageio.ImageReader) iter.next();\r
117                         return imageCodec;\r
118                 }\r
119 \r
120                 public static ImageCodec CreateWriter(ImageFormat imageFormat) {\r
121                         return CreateWriter( ImageFormatToClsid( imageFormat ) );\r
122                 }\r
123 \r
124                 public static ImageCodec CreateWriter(Guid clsid) {\r
125                         ImageCodec codec = null;\r
126                         try {\r
127                                 ImageCodecInfo codecInfo = FindEncoder(clsid);\r
128                                 java.util.Iterator iter = imageio.ImageIO.getImageWritersByMIMEType( codecInfo.MimeType );\r
129                                 codec = CreateWriter(iter);\r
130                         }\r
131                         catch {}\r
132 \r
133                         if (codec == null) {\r
134                                 ImageFormat format = ClsidToImageFormat(clsid);\r
135                                 string name = (format != null) ? format.ToString() : clsid.ToString();\r
136                                 throw new NotSupportedException(String.Format("The '{0}' format encoder is not installed.", name));\r
137                         }\r
138 \r
139                         return codec;\r
140                 }\r
141 \r
142                 private static ImageCodec CreateWriter(java.util.Iterator iter) {\r
143                         if ( !iter.hasNext() )
144                                 return null;
145                         \r
146                         ImageCodec imageCodec = new ImageCodec();\r
147                         imageCodec.NativeWriter = (imageio.ImageWriter) iter.next();\r
148                         return imageCodec;\r
149                 }\r
150 \r
151                 #endregion\r
152 \r
153                 #region Codec enumerations\r
154 \r
155                 internal static Hashtable Decoders {
156                         get {
157                                 const string MYNAME = "System.Drawing.Imaging.ImageCodecInfo.decoders";
158                                 Hashtable o = (Hashtable) AppDomain.CurrentDomain.GetData (MYNAME);
159                                 if (o != null)
160                                         return o;
161                                 o = new ReaderSpiIterator().Iterate();
162                                 AppDomain.CurrentDomain.SetData(MYNAME, o);
163                                 return o;
164                         }
165                 }
166
167                 internal static Hashtable Encoders {
168                         get {
169                                 const string MYNAME = "System.Drawing.Imaging.ImageCodecInfo.encoders";
170                                 Hashtable o = (Hashtable) AppDomain.CurrentDomain.GetData (MYNAME);
171                                 if (o != null)
172                                         return o;
173                                 o = new WriterSpiIterator().Iterate();
174                                 AppDomain.CurrentDomain.SetData(MYNAME, o);
175                                 return o;
176                         }
177                 }
178
179                 internal static ImageCodecInfo FindEncoder (Guid clsid) {
180                         ImageCodecInfo codec = (ImageCodecInfo) Encoders[clsid];
181                         if (codec == null) {
182                                 // .net saves in png if cannot find requested encoder. atc id 316563
183                                 codec = (ImageCodecInfo) Encoders[ ImageCodec.PngClsid ];
184                         }
185                         return codec;
186                 }
187
188                 internal static ImageCodecInfo FindDecoder (Guid clsid) {
189                         ImageCodecInfo codec = (ImageCodecInfo) Decoders[clsid];
190                         if (codec == null) {\r
191                                 ImageFormat format = ClsidToImageFormat(clsid);\r
192                                 string name = (format != null) ? format.ToString() : clsid.ToString();\r
193                                 throw new NotSupportedException(String.Format("The '{0}' format decoder is not installed.", name));\r
194                         }\r
195                         return codec;\r
196                 }
197 \r
198                 #endregion\r
199 \r
200                 #region SpiIterators
201
202                 abstract class BaseSpiIterator {
203                         protected abstract java.util.Iterator GetIterator (string mimeType);
204                         protected abstract spi.ImageReaderWriterSpi GetNext (java.util.Iterator iter);
205
206                         #region ProcessOneCodec
207                         private ImageCodecInfo ProcessOneCodec (Guid clsid, Guid formatID, string mimeType) {
208                                 ImageCodecInfo ici = new ImageCodecInfo ();
209                                 ici.Clsid = clsid;
210                                 ici.FormatID = formatID;
211                                 ici.MimeType = mimeType;
212                                 java.util.Iterator iter = null;
213                                 try {
214                                         iter = GetIterator (mimeType);
215                                 }
216                                 catch(Exception) {
217                                         return null;
218                                 }
219                                 while (iter.hasNext ()) {
220                                         spi.ImageReaderWriterSpi rw = GetNext (iter);
221
222                                         ici.CodecName = rw.getDescription (java.util.Locale.getDefault ());
223                                         //ici.DllName = null;
224                                         foreach (string suffix in rw.getFileSuffixes ()) {
225                                                 if (ici.FilenameExtension != null)
226                                                         ici.FilenameExtension += ";";
227                                                 ici.FilenameExtension += "*."+suffix;
228                                         }
229                                         ici.Flags = ImageCodecFlags.Builtin|ImageCodecFlags.SupportBitmap;
230                                         if (rw is spi.ImageReaderSpi)
231                                                 ici.Flags |= ImageCodecFlags.Decoder;
232
233                                         if (rw is spi.ImageWriterSpi)
234                                                 ici.Flags |= ImageCodecFlags.Encoder;
235
236                                         ici.FormatDescription = string.Join(";",
237                                                 rw.getFormatNames());
238                                         try {
239                                                 ici.Version = (int)Convert.ToDouble(rw.getVersion ());
240                                         }
241                                         catch (Exception) {
242                                                 ici.Version = 1;
243                                         }
244                                         break;
245                                 }
246                                 return ici;
247                         }
248                         #endregion
249
250                         internal Hashtable Iterate () {
251                                 // TBD: Insert Exception handling here
252                                 NameValueCollection nvc = (NameValueCollection) System.Configuration.ConfigurationSettings\r
253                                         .GetConfig ("mainsoft.drawing/codecs");
254                                 Hashtable codecs = new Hashtable (10);
255                         
256                                 for (int i=0; i<nvc.Count; i++) {
257                                         Guid clsid = new Guid (nvc.GetKey (i));
258                                         ImageFormat format = ClsidToImageFormat (clsid);
259                                         ImageCodecInfo codec = ProcessOneCodec (clsid, format.Guid, nvc[i]);
260                                         if ((codec != null) && (codec.FilenameExtension != null))
261                                                 codecs [clsid] = codec;
262                                 }
263                                 return codecs;
264                         }
265                 }
266
267                 class ReaderSpiIterator: BaseSpiIterator {
268                         protected override java.util.Iterator GetIterator(string mimeType) {\r
269                                 return imageio.ImageIO.getImageReadersByMIMEType (mimeType);\r
270                         }\r
271                         protected override javax.imageio.spi.ImageReaderWriterSpi GetNext(java.util.Iterator iter) {\r
272                                 imageio.ImageReader r = (imageio.ImageReader) iter.next ();\r
273                                 return r.getOriginatingProvider ();\r
274                         }\r
275                 }
276
277                 class WriterSpiIterator: BaseSpiIterator {
278                         protected override java.util.Iterator GetIterator(string mimeType) {\r
279                                 return imageio.ImageIO.getImageWritersByMIMEType (mimeType);\r
280                         }\r
281                         protected override javax.imageio.spi.ImageReaderWriterSpi GetNext(java.util.Iterator iter) {\r
282                                 imageio.ImageWriter w = (imageio.ImageWriter) iter.next ();\r
283                                 return w.getOriginatingProvider ();\r
284                         }\r
285                 }
286                 #endregion
287 \r
288                 #region Clsid and FormatID
289                 static Guid BmpClsid = new Guid ("557cf400-1a04-11d3-9a73-0000f81ef32e");
290                 static Guid JpegClsid = new Guid ("557cf401-1a04-11d3-9a73-0000f81ef32e");
291                 static Guid GifClsid = new Guid ("557cf402-1a04-11d3-9a73-0000f81ef32e");
292                 static Guid EmfClsid = new Guid ("557cf403-1a04-11d3-9a73-0000f81ef32e");
293                 static Guid WmfClsid = new Guid ("557cf404-1a04-11d3-9a73-0000f81ef32e");
294                 static Guid TiffClsid = new Guid ("557cf405-1a04-11d3-9a73-0000f81ef32e");
295                 static Guid PngClsid = new Guid ("557cf406-1a04-11d3-9a73-0000f81ef32e");
296                 static Guid IconClsid = new Guid ("557cf407-1a04-11d3-9a73-0000f81ef32e");
297
298                 private static ImageFormat MimeTypesToImageFormat (string [] mimeTypes) {
299                         foreach (ImageCodecInfo codec in Decoders.Values)
300                                 for (int i=0; i<mimeTypes.Length; i++)\r
301                                         if (codec.MimeType == mimeTypes [i])\r
302                                                 return ClsidToImageFormat (codec.Clsid);\r
303                         return null;
304                 }
305
306                 internal static ImageFormat ClsidToImageFormat (Guid clsid) {
307                         if (clsid.Equals (BmpClsid))
308                                 return ImageFormat.Bmp;
309                         else if (clsid.Equals (JpegClsid))
310                                 return ImageFormat.Jpeg;
311                         else if (clsid.Equals (GifClsid))
312                                 return ImageFormat.Gif;
313                         else if (clsid.Equals (EmfClsid))
314                                 return ImageFormat.Emf;
315                         else if (clsid.Equals (WmfClsid))
316                                 return ImageFormat.Wmf;
317                         else if (clsid.Equals (TiffClsid))
318                                 return ImageFormat.Tiff;
319                         else if (clsid.Equals (PngClsid))
320                                 return ImageFormat.Png;
321                         else if (clsid.Equals (IconClsid))
322                                 return ImageFormat.Icon;
323                         else
324                                 return null;
325                 }
326
327                 internal static Guid ImageFormatToClsid (ImageFormat format) {
328                         if (format == null)
329                                 return Guid.Empty;
330
331                         if (format.Guid.Equals (ImageFormat.Bmp.Guid))
332                                 return BmpClsid;
333                         else if (format.Guid.Equals (ImageFormat.Jpeg.Guid))
334                                 return JpegClsid;
335                         else if (format.Guid.Equals (ImageFormat.Gif))
336                                 return GifClsid;
337                         else if (format.Guid.Equals (ImageFormat.Emf.Guid))
338                                 return EmfClsid;
339                         else if (format.Guid.Equals (ImageFormat.Wmf.Guid))
340                                 return WmfClsid;
341                         else if (format.Guid.Equals (ImageFormat.Tiff.Guid))
342                                 return TiffClsid;
343                         else if (format.Guid.Equals (ImageFormat.Png.Guid))
344                                 return PngClsid;
345                         else if (format.Guid.Equals (ImageFormat.Icon.Guid))
346                                 return IconClsid;
347                         else
348                                 return Guid.Empty;
349                 }
350
351                 private FrameDimension FormatFrameDimesion {
352                         get {
353                                 if (ImageFormat == null)
354                                         return FrameDimension.Page;
355
356                                 if (ImageFormat.Guid.Equals (ImageFormat.Bmp.Guid))
357                                         return FrameDimension.Page;
358                                 else if (ImageFormat.Guid.Equals (ImageFormat.Jpeg.Guid))
359                                         return FrameDimension.Page;
360                                 else if (ImageFormat.Guid.Equals (ImageFormat.Gif))
361                                         return FrameDimension.Time;
362                                 else if (ImageFormat.Guid.Equals (ImageFormat.Emf.Guid))
363                                         return FrameDimension.Page;
364                                 else if (ImageFormat.Guid.Equals (ImageFormat.Wmf.Guid))
365                                         return FrameDimension.Page;
366                                 else if (ImageFormat.Guid.Equals (ImageFormat.Tiff.Guid))
367                                         return FrameDimension.Page;
368                                 else if (ImageFormat.Guid.Equals (ImageFormat.Png.Guid))
369                                         return FrameDimension.Page;
370                                 else if (ImageFormat.Guid.Equals (ImageFormat.Icon.Guid))
371                                         return FrameDimension.Resolution;
372                                 else
373                                         return FrameDimension.Page;
374                         }
375                 }
376
377                 #endregion
378                 \r
379                 #region Image read/write methods\r
380 \r
381                 internal PlainImage ReadPlainImage() {\r
382                         awt.Image img = ReadImage( _currentFrame );\r
383                         if (img == null)\r
384                                 return null;\r
385 \r
386                         // its possible to fail to load thumbnails and metadata, but image is ok.\r
387                         awt.Image [] th = null;\r
388 #if THUMBNAIL_SUPPORTED\r
389                         try {\r
390                                 th = ReadThumbnails( _currentFrame );\r
391                         }\r
392                         catch (Exception) {}\r
393 #endif\r
394                         \r
395                         XmlDocument md = null;\r
396                         imageio.metadata.IIOMetadata nativeMd = null;\r
397                         try {\r
398                                 nativeMd = ReadImageMetadata( _currentFrame );\r
399                                 md = ConvertImageMetadata( nativeMd );\r
400                         }\r
401                         catch (Exception) {}\r
402 \r
403                         float [] resolution = GetResolution( md );\r
404 \r
405                         PlainImage pi = new PlainImage( img, th, ImageFormat, resolution[0], resolution[1], FormatFrameDimesion );\r
406                         pi.NativeMetadata = nativeMd;\r
407                         return pi;\r
408                 }\r
409 \r
410                 internal PlainImage ReadNextPlainImage() {\r
411                         _currentFrame++;\r
412                         return ReadPlainImage();\r
413                 }\r
414 \r
415                 private awt.Image ReadImage(int frame) {\r
416                         if (NativeStream == null)\r
417                                 throw new Exception("Input stream not specified");\r
418 \r
419                         try {\r
420                                 return NativeReader.read (frame);
421                         }
422                         catch (java.lang.IndexOutOfBoundsException) {
423                                 return null;
424                         }
425                         catch (java.io.IOException ex) {
426                                 throw new System.IO.IOException(ex.Message, ex);
427                         }
428                 }\r
429 \r
430 #if THUMBNAIL_SUPPORTED\r
431                 private awt.Image [] ReadThumbnails(int frameIndex) {\r
432                         awt.Image [] thArray = null;
433
434                         try {
435                                 if (NativeReader.readerSupportsThumbnails()) {
436                                         int tmbNumber = NativeReader.getNumThumbnails(frameIndex);
437
438                                         if (tmbNumber > 0) {
439                                                 thArray = new awt.Image[ tmbNumber ];
440
441                                                 for (int i = 0; i < tmbNumber; i++) {
442                                                         thArray[i] = NativeReader.readThumbnail(frameIndex, i);
443                                                 }
444                                         }
445                                 }\r
446                                 return thArray;\r
447                         }\r
448                         catch (java.io.IOException ex) {
449                                 throw new System.IO.IOException(ex.Message, ex);
450                         }
451                 }\r
452 #endif\r
453                 internal void WritePlainImage(PlainImageCollection pic) {\r
454                         if ((pic == null) || (pic.Count == 0))\r
455                                 return;\r
456 \r
457                         if (pic.Count == 1) {\r
458                                 WritePlainImage( pic[0] );\r
459                                 return;\r
460                         }\r
461 \r
462                         try {\r
463                                 if (NativeWriter.canWriteSequence ()) {\r
464                                         NativeWriter.prepareWriteSequence (null);\r
465                                         for (int i=0; i < pic.Count; i++) {\r
466                                                 imageio.IIOImage iio = GetIIOImageContainer( pic[i] );\r
467                                                 NativeWriter.writeToSequence (iio, null);\r
468                                         }\r
469                                         NativeWriter.endWriteSequence ();\r
470                                 }\r
471                                 else\r
472                                         WritePlainImage( pic[0] );\r
473                         }\r
474                         catch (java.io.IOException ex) {
475                                 throw new System.IO.IOException(ex.Message, ex);
476                         }
477                 }\r
478 \r
479                 internal void WritePlainImage(PlainImage pi) {\r
480                         try {\r
481                                 imageio.IIOImage iio = GetIIOImageContainer( pi );\r
482                                 WriteImage( iio );\r
483                         }\r
484                         catch (java.io.IOException ex) {
485                                 throw new System.IO.IOException(ex.Message, ex);
486                         }\r
487                 }\r
488 \r
489                 private void WriteImage(imageio.IIOImage iio) {\r
490                         if (NativeStream == null)\r
491                                 throw new Exception("Output stream not specified");\r
492 \r
493                         NativeWriter.write( iio );\r
494                 }\r
495                 \r
496                 private imageio.IIOImage GetIIOImageContainer(PlainImage pi) {\r
497                         java.util.ArrayList al = null;\r
498                         \r
499                         // prepare thumbnails list\r
500                         if (pi.Thumbnails != null) {\r
501                                 al = new java.util.ArrayList( pi.Thumbnails.Length );\r
502                                 for (int i=0; i < pi.Thumbnails.Length; i++)\r
503                                         al.add(pi.Thumbnails[i]);\r
504                         }\r
505 \r
506                         // prepare IIOImage container\r
507                         if (pi.NativeImage is image.BufferedImage) {\r
508                                 imageio.IIOImage iio = new javax.imageio.IIOImage(\r
509                                         (image.BufferedImage)pi.NativeImage, al, null /*pi.NativeMetadata*/);\r
510                                 return iio;\r
511                         }\r
512                         else\r
513                                 // TBD: This codec is for raster formats only\r
514                                 throw new NotSupportedException("Only raster formats are supported");\r
515                 }\r
516 \r
517 \r
518                 private imageio.metadata.IIOMetadata ReadImageMetadata(int frameIndex) {\r
519                         if (NativeStream == null)\r
520                                 throw new Exception("Input stream not specified");\r
521 \r
522                         try {\r
523                                 imageio.metadata.IIOMetadata md = NativeReader.getImageMetadata( frameIndex );\r
524                                 return md;\r
525                         }\r
526                         catch (java.io.IOException ex) {
527                                 throw new System.IO.IOException(ex.Message, ex);
528                         }
529                 }\r
530 \r
531                 #endregion\r
532 \r
533                 #region Extra properties\r
534 \r
535                 public ImageFormat ImageFormat {\r
536                         get { return _imageFormat; }\r
537                 }\r
538 \r
539                 #endregion\r
540 \r
541                 #region Metadata parse\r
542 \r
543                 private float [] GetResolution(XmlDocument metaData) {\r
544                         if (metaData == null)\r
545                                 return new float[]{0, 0};\r
546 \r
547                         ResolutionConfigurationCollection rcc = 
548                                 (ResolutionConfigurationCollection)\r
549                                 ConfigurationSettings.GetConfig ("mainsoft.drawing/codecsmetadata");
550
551                         if (rcc == null)
552                                 throw new ConfigurationException("Configuration section codecsmetadata not found");
553
554                         ResolutionConfiguration rc = rcc[ ImageFormat.ToString() ];
555
556                         if (rc == null)
557                                 return new float[]{0, 0};
558
559                         // Horizontal resolution
560                         string xResPath = rc.XResPath;
561                         string xRes;
562
563                         if (xResPath == string.Empty)
564                                 xRes = rc.XResDefault;
565                         else
566                                 xRes = GetValueFromMetadata(metaData, xResPath);
567
568                         if ((xRes == null) || (xRes == string.Empty))
569                                 xRes = rc.XResDefault;
570
571                         // Vertical resolution
572                         string yResPath = rc.YResPath;
573                         string yRes;
574
575                         if (yResPath == string.Empty)
576                                 yRes = rc.YResDefault;
577                         else
578                                 yRes = GetValueFromMetadata(metaData, yResPath);
579
580                         if ((yRes == null) || (yRes == string.Empty))
581                                 yRes = rc.YResDefault;
582
583                         // Resolution units
584                         string resUnitsPath = rc.UnitsTypePath;
585                         string resUnitsType;
586
587                         if (resUnitsPath == string.Empty)
588                                 resUnitsType = rc.UnitsTypeDefault;
589                         else
590                                 resUnitsType = GetValueFromMetadata(metaData, resUnitsPath);
591
592                         if (resUnitsType == null)
593                                 resUnitsType = rc.UnitsTypeDefault;
594
595                         // Unit scale
596                         string unitScale = rc.UnitsScale[resUnitsType].ToString();
597
598                         // Adjust resolution to its units
599                         float [] res = new float[2];
600                         res[0] = ParseFloatValue(xRes) * ParseFloatValue(unitScale);
601                         res[1] = ParseFloatValue(yRes) * ParseFloatValue(unitScale);
602
603                         return res;
604                 }\r
605 \r
606                 private string GetValueFromMetadata(XmlDocument metaData, string path) {\r
607                         XmlNode n = metaData.SelectSingleNode(path);\r
608                         if (n == null)\r
609                                 return null;\r
610 \r
611                         return n.InnerText;\r
612                 }\r
613 \r
614                 private XmlDocument ConvertImageMetadata(imageio.metadata.IIOMetadata metaData) {\r
615                         string [] formatNames = metaData.getMetadataFormatNames();
616                         dom.Element rootNode = (dom.Element) metaData.getAsTree(formatNames[0]);
617
618                         XmlDocument _metadataDocument = new XmlDocument();\r
619                         XmlConvert(rootNode, _metadataDocument);\r
620 \r
621                         return _metadataDocument;\r
622                 }\r
623 \r
624                 private void XmlConvert(dom.Node jNode, XmlNode nNode) {\r
625                         XmlDocument document = nNode.OwnerDocument;\r
626                         if (document == null)\r
627                                 document = (XmlDocument)nNode;\r
628 \r
629                         XmlNode n = null;\r
630                         switch (jNode.getNodeType()) {\r
631                                 case 1 :\r
632                                         n = document.CreateNode(XmlNodeType.Element, jNode.getNodeName(), jNode.getNamespaceURI());\r
633                                         break;\r
634 \r
635                                 case 4 :\r
636                                         n = document.CreateNode(XmlNodeType.CDATA, jNode.getNodeName(), jNode.getNamespaceURI());\r
637                                         break;\r
638 \r
639                                 default:\r
640                                         return;\r
641                         }\r
642                         //set value\r
643                         n.InnerText = jNode.getNodeValue();\r
644                         nNode.AppendChild( n );\r
645 \r
646                         //copy attributes\r
647                         org.w3c.dom.NamedNodeMap nm = jNode.getAttributes();\r
648                         for (int i=0; i<nm.getLength(); i++) {\r
649                                 XmlAttribute a = document.CreateAttribute( nm.item(i).getNodeName() );\r
650                                 a.Value = nm.item(i).getNodeValue();\r
651                                 n.Attributes.Append( a );\r
652                         }\r
653 \r
654                         //copy childs\r
655                         org.w3c.dom.NodeList nl = jNode.getChildNodes();\r
656                         for (int i=0; i<nl.getLength(); i++) {\r
657                                 XmlConvert(nl.item(i), n);\r
658                         }\r
659                 }\r
660 \r
661                 protected virtual float ParseFloatValue(string strValue) {\r
662                         try {\r
663                                 if ((strValue != null) && (strValue != "")) {
664                                         int dividerPos = strValue.IndexOf("/");
665                                 
666                                         if (dividerPos < 0) {
667                                                 return float.Parse(strValue);
668                                         } 
669                                         else {
670                                                 return float.Parse(strValue.Substring( 0, dividerPos )) /
671                                                         float.Parse(strValue.Substring( dividerPos + 1 ));
672                                         }
673                                 }\r
674                                 return float.NaN;\r
675                         }\r
676                         catch (Exception) {\r
677                                 return float.NaN;\r
678                         }\r
679                 }\r
680 \r
681                 #endregion\r
682 \r
683                 #region IDisposable members\r
684 \r
685                 public void Dispose() {\r
686                         if (NativeReader != null) {\r
687                                 NativeReader.dispose();\r
688                                 NativeReader = null;\r
689                         }\r
690 \r
691                         if (NativeWriter != null) {\r
692                                 NativeWriter.dispose();\r
693                                 NativeWriter = null;\r
694                         }\r
695                 }\r
696 \r
697                 #endregion\r
698 \r
699         }\r
700 }\r