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