diff options
Diffstat (limited to 'mcs/class/System.Drawing/System.Drawing.Imaging/ImageCodec.jvm.cs')
-rw-r--r-- | mcs/class/System.Drawing/System.Drawing.Imaging/ImageCodec.jvm.cs | 700 |
1 files changed, 700 insertions, 0 deletions
diff --git a/mcs/class/System.Drawing/System.Drawing.Imaging/ImageCodec.jvm.cs b/mcs/class/System.Drawing/System.Drawing.Imaging/ImageCodec.jvm.cs new file mode 100644 index 00000000000..2eff947138a --- /dev/null +++ b/mcs/class/System.Drawing/System.Drawing.Imaging/ImageCodec.jvm.cs @@ -0,0 +1,700 @@ +using System;
+using System.Configuration;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Drawing.Imaging;
+using System.Xml;
+using Mainsoft.Drawing.Configuration;
+
+using imageio = javax.imageio;
+using stream = javax.imageio.stream;
+using awt = java.awt;
+using image = java.awt.image;
+using spi = javax.imageio.spi;
+using dom = org.w3c.dom;
+
+namespace Mainsoft.Drawing.Imaging {
+ /// <summary>
+ /// Summary description for ImageCodec.
+ /// </summary>
+ public class ImageCodec : IDisposable {
+
+ #region Members
+
+ imageio.ImageReader _nativeReader = null;
+ imageio.ImageWriter _nativeWriter = null;
+ stream.ImageInputStream _nativeStream = null;
+
+ ImageFormat _imageFormat = null;
+
+ int _currentFrame = 0;
+
+ #endregion
+
+ #region Constructros
+
+ protected ImageCodec() {
+ }
+
+ static ImageCodec() {
+ }
+
+ #endregion
+
+ #region Internal properties
+
+ internal imageio.ImageReader NativeReader {
+ get { return _nativeReader; }
+ set {
+ _nativeReader = value;
+ if (value == null)
+ return;
+ _imageFormat = MimeTypesToImageFormat( value.getOriginatingProvider().getMIMETypes() );
+ }
+ }
+ internal imageio.ImageWriter NativeWriter {
+ get { return _nativeWriter; }
+ set {
+ _nativeWriter = value;
+ if (value == null)
+ return;
+ _imageFormat = MimeTypesToImageFormat( value.getOriginatingProvider().getMIMETypes() );
+ }
+ }
+
+ internal stream.ImageInputStream NativeStream {
+ get { return _nativeStream; }
+ set {
+ _nativeStream = value;
+ if (value == null)
+ return;
+
+ if (NativeReader != null)
+ NativeReader.setInput( value );
+
+ if (NativeWriter != null)
+ NativeWriter.setOutput( value );
+ }
+ }
+
+ #endregion
+
+ #region ImageCodec factory methods
+
+ public static ImageCodec CreateReader(stream.ImageInputStream inputStream) {
+ java.util.Iterator iter = imageio.ImageIO.getImageReaders( inputStream );
+ return CreateReader(iter);
+ }
+
+ public static ImageCodec CreateReader(ImageFormat imageFormat) {
+ return CreateReader( ImageFormatToClsid( imageFormat ) );
+ }
+
+ public static ImageCodec CreateReader(Guid clsid) {
+ ImageCodec codec = null;
+ try {
+ ImageCodecInfo codecInfo = FindDecoder(clsid);
+ java.util.Iterator iter = imageio.ImageIO.getImageReadersByMIMEType( codecInfo.MimeType );
+ codec = CreateReader(iter);
+ }
+ catch {}
+
+ if (codec == null) {
+ ImageFormat format = ClsidToImageFormat(clsid);
+ string name = (format != null) ? format.ToString() : clsid.ToString();
+ throw new NotSupportedException(String.Format("The '{0}' format decoder is not installed.", name));
+ }
+
+ return codec;
+ }
+
+ private static ImageCodec CreateReader(java.util.Iterator iter) {
+ if ( !iter.hasNext() ) + return null; +
+ ImageCodec imageCodec = new ImageCodec();
+ imageCodec.NativeReader = (imageio.ImageReader) iter.next();
+ return imageCodec;
+ }
+
+ public static ImageCodec CreateWriter(ImageFormat imageFormat) {
+ return CreateWriter( ImageFormatToClsid( imageFormat ) );
+ }
+
+ public static ImageCodec CreateWriter(Guid clsid) {
+ ImageCodec codec = null;
+ try {
+ ImageCodecInfo codecInfo = FindEncoder(clsid);
+ java.util.Iterator iter = imageio.ImageIO.getImageWritersByMIMEType( codecInfo.MimeType );
+ codec = CreateWriter(iter);
+ }
+ catch {}
+
+ if (codec == null) {
+ ImageFormat format = ClsidToImageFormat(clsid);
+ string name = (format != null) ? format.ToString() : clsid.ToString();
+ throw new NotSupportedException(String.Format("The '{0}' format encoder is not installed.", name));
+ }
+
+ return codec;
+ }
+
+ private static ImageCodec CreateWriter(java.util.Iterator iter) {
+ if ( !iter.hasNext() ) + return null; +
+ ImageCodec imageCodec = new ImageCodec();
+ imageCodec.NativeWriter = (imageio.ImageWriter) iter.next();
+ return imageCodec;
+ }
+
+ #endregion
+
+ #region Codec enumerations
+
+ internal static Hashtable Decoders { + get { + const string MYNAME = "System.Drawing.Imaging.ImageCodecInfo.decoders"; + Hashtable o = (Hashtable) AppDomain.CurrentDomain.GetData (MYNAME); + if (o != null) + return o; + o = new ReaderSpiIterator().Iterate(); + AppDomain.CurrentDomain.SetData(MYNAME, o); + return o; + } + } + + internal static Hashtable Encoders { + get { + const string MYNAME = "System.Drawing.Imaging.ImageCodecInfo.encoders"; + Hashtable o = (Hashtable) AppDomain.CurrentDomain.GetData (MYNAME); + if (o != null) + return o; + o = new WriterSpiIterator().Iterate(); + AppDomain.CurrentDomain.SetData(MYNAME, o); + return o; + } + } + + internal static ImageCodecInfo FindEncoder (Guid clsid) { + ImageCodecInfo codec = (ImageCodecInfo) Encoders[clsid]; + if (codec == null) { + // .net saves in png if cannot find requested encoder. atc id 316563 + codec = (ImageCodecInfo) Encoders[ ImageCodec.PngClsid ]; + } + return codec; + } + + internal static ImageCodecInfo FindDecoder (Guid clsid) { + ImageCodecInfo codec = (ImageCodecInfo) Decoders[clsid]; + if (codec == null) {
+ ImageFormat format = ClsidToImageFormat(clsid);
+ string name = (format != null) ? format.ToString() : clsid.ToString();
+ throw new NotSupportedException(String.Format("The '{0}' format decoder is not installed.", name));
+ }
+ return codec;
+ } +
+ #endregion
+
+ #region SpiIterators + + abstract class BaseSpiIterator { + protected abstract java.util.Iterator GetIterator (string mimeType); + protected abstract spi.ImageReaderWriterSpi GetNext (java.util.Iterator iter); + + #region ProcessOneCodec + private ImageCodecInfo ProcessOneCodec (Guid clsid, Guid formatID, string mimeType) { + ImageCodecInfo ici = new ImageCodecInfo (); + ici.Clsid = clsid; + ici.FormatID = formatID; + ici.MimeType = mimeType; + java.util.Iterator iter = null; + try { + iter = GetIterator (mimeType); + } + catch(Exception) { + return null; + } + while (iter.hasNext ()) { + spi.ImageReaderWriterSpi rw = GetNext (iter); + + ici.CodecName = rw.getDescription (java.util.Locale.getDefault ()); + //ici.DllName = null; + foreach (string suffix in rw.getFileSuffixes ()) { + if (ici.FilenameExtension != null) + ici.FilenameExtension += ";"; + ici.FilenameExtension += "*."+suffix; + } + ici.Flags = ImageCodecFlags.Builtin|ImageCodecFlags.SupportBitmap; + if (rw is spi.ImageReaderSpi) + ici.Flags |= ImageCodecFlags.Decoder; + + if (rw is spi.ImageWriterSpi) + ici.Flags |= ImageCodecFlags.Encoder; + + ici.FormatDescription = string.Join(";", + rw.getFormatNames()); + try { + ici.Version = (int)Convert.ToDouble(rw.getVersion ()); + } + catch (Exception) { + ici.Version = 1; + } + break; + } + return ici; + } + #endregion + + internal Hashtable Iterate () { + // TBD: Insert Exception handling here + NameValueCollection nvc = (NameValueCollection) System.Configuration.ConfigurationSettings + .GetConfig ("system.drawing/codecs"); + Hashtable codecs = new Hashtable (10); + + for (int i=0; i<nvc.Count; i++) { + Guid clsid = new Guid (nvc.GetKey (i)); + ImageFormat format = ClsidToImageFormat (clsid); + ImageCodecInfo codec = ProcessOneCodec (clsid, format.Guid, nvc[i]); + if ((codec != null) && (codec.FilenameExtension != null)) + codecs [clsid] = codec; + } + return codecs; + } + } + + class ReaderSpiIterator: BaseSpiIterator { + protected override java.util.Iterator GetIterator(string mimeType) {
+ return imageio.ImageIO.getImageReadersByMIMEType (mimeType);
+ }
+ protected override javax.imageio.spi.ImageReaderWriterSpi GetNext(java.util.Iterator iter) {
+ imageio.ImageReader r = (imageio.ImageReader) iter.next ();
+ return r.getOriginatingProvider ();
+ }
+ } + + class WriterSpiIterator: BaseSpiIterator { + protected override java.util.Iterator GetIterator(string mimeType) {
+ return imageio.ImageIO.getImageWritersByMIMEType (mimeType);
+ }
+ protected override javax.imageio.spi.ImageReaderWriterSpi GetNext(java.util.Iterator iter) {
+ imageio.ImageWriter w = (imageio.ImageWriter) iter.next ();
+ return w.getOriginatingProvider ();
+ }
+ } + #endregion +
+ #region Clsid and FormatID + static Guid BmpClsid = new Guid ("557cf400-1a04-11d3-9a73-0000f81ef32e"); + static Guid JpegClsid = new Guid ("557cf401-1a04-11d3-9a73-0000f81ef32e"); + static Guid GifClsid = new Guid ("557cf402-1a04-11d3-9a73-0000f81ef32e"); + static Guid EmfClsid = new Guid ("557cf403-1a04-11d3-9a73-0000f81ef32e"); + static Guid WmfClsid = new Guid ("557cf404-1a04-11d3-9a73-0000f81ef32e"); + static Guid TiffClsid = new Guid ("557cf405-1a04-11d3-9a73-0000f81ef32e"); + static Guid PngClsid = new Guid ("557cf406-1a04-11d3-9a73-0000f81ef32e"); + static Guid IconClsid = new Guid ("557cf407-1a04-11d3-9a73-0000f81ef32e"); + + private static ImageFormat MimeTypesToImageFormat (string [] mimeTypes) { + foreach (ImageCodecInfo codec in Decoders.Values) + for (int i=0; i<mimeTypes.Length; i++) + if (codec.MimeType == mimeTypes [i]) + return new ImageFormat (codec.FormatID); + return null; + } + + internal static ImageFormat ClsidToImageFormat (Guid clsid) { + if (clsid.Equals (BmpClsid)) + return ImageFormat.Bmp; + else if (clsid.Equals (JpegClsid)) + return ImageFormat.Jpeg; + else if (clsid.Equals (GifClsid)) + return ImageFormat.Gif; + else if (clsid.Equals (EmfClsid)) + return ImageFormat.Emf; + else if (clsid.Equals (WmfClsid)) + return ImageFormat.Wmf; + else if (clsid.Equals (TiffClsid)) + return ImageFormat.Tiff; + else if (clsid.Equals (PngClsid)) + return ImageFormat.Png; + else if (clsid.Equals (IconClsid)) + return ImageFormat.Icon; + else + return null; + } + + internal static Guid ImageFormatToClsid (ImageFormat format) { + if (format == null) + return Guid.Empty; + + if (format.Guid.Equals (ImageFormat.Bmp.Guid)) + return BmpClsid; + else if (format.Guid.Equals (ImageFormat.Jpeg.Guid)) + return JpegClsid; + else if (format.Guid.Equals (ImageFormat.Gif)) + return GifClsid; + else if (format.Guid.Equals (ImageFormat.Emf.Guid)) + return EmfClsid; + else if (format.Guid.Equals (ImageFormat.Wmf.Guid)) + return WmfClsid; + else if (format.Guid.Equals (ImageFormat.Tiff.Guid)) + return TiffClsid; + else if (format.Guid.Equals (ImageFormat.Png.Guid)) + return PngClsid; + else if (format.Guid.Equals (ImageFormat.Icon.Guid)) + return IconClsid; + else + return Guid.Empty; + } + + private FrameDimension FormatFrameDimesion { + get { + if (ImageFormat == null) + return FrameDimension.Page; + + if (ImageFormat.Guid.Equals (ImageFormat.Bmp.Guid)) + return FrameDimension.Page; + else if (ImageFormat.Guid.Equals (ImageFormat.Jpeg.Guid)) + return FrameDimension.Page; + else if (ImageFormat.Guid.Equals (ImageFormat.Gif)) + return FrameDimension.Time; + else if (ImageFormat.Guid.Equals (ImageFormat.Emf.Guid)) + return FrameDimension.Page; + else if (ImageFormat.Guid.Equals (ImageFormat.Wmf.Guid)) + return FrameDimension.Page; + else if (ImageFormat.Guid.Equals (ImageFormat.Tiff.Guid)) + return FrameDimension.Page; + else if (ImageFormat.Guid.Equals (ImageFormat.Png.Guid)) + return FrameDimension.Page; + else if (ImageFormat.Guid.Equals (ImageFormat.Icon.Guid)) + return FrameDimension.Resolution; + else + return FrameDimension.Page; + } + } + + #endregion +
+ #region Image read/write methods
+
+ internal PlainImage ReadPlainImage() {
+ awt.Image img = ReadImage( _currentFrame );
+ if (img == null)
+ return null;
+
+ // its possible to fail to load thumbnails and metadata, but image is ok.
+ awt.Image [] th = null;
+#if THUMBNAIL_SUPPORTED
+ try {
+ th = ReadThumbnails( _currentFrame );
+ }
+ catch (Exception) {}
+#endif
+
+ XmlDocument md = null;
+ imageio.metadata.IIOMetadata nativeMd = null;
+ try {
+ nativeMd = ReadImageMetadata( _currentFrame );
+ md = ConvertImageMetadata( nativeMd );
+ }
+ catch (Exception) {}
+
+ float [] resolution = GetResolution( md );
+
+ PlainImage pi = new PlainImage( img, th, ImageFormat, resolution[0], resolution[1], FormatFrameDimesion );
+ pi.NativeMetadata = nativeMd;
+ return pi;
+ }
+
+ internal PlainImage ReadNextPlainImage() {
+ _currentFrame++;
+ return ReadPlainImage();
+ }
+
+ private awt.Image ReadImage(int frame) {
+ if (NativeStream == null)
+ throw new Exception("Input stream not specified");
+
+ try {
+ return NativeReader.read (frame); + } + catch (java.lang.IndexOutOfBoundsException) { + return null; + } + catch (java.io.IOException ex) { + throw new System.IO.IOException(ex.Message, ex); + } + }
+
+#if THUMBNAIL_SUPPORTED
+ private awt.Image [] ReadThumbnails(int frameIndex) {
+ awt.Image [] thArray = null; + + try { + if (NativeReader.readerSupportsThumbnails()) { + int tmbNumber = NativeReader.getNumThumbnails(frameIndex); + + if (tmbNumber > 0) { + thArray = new awt.Image[ tmbNumber ]; + + for (int i = 0; i < tmbNumber; i++) { + thArray[i] = NativeReader.readThumbnail(frameIndex, i); + } + } + }
+ return thArray;
+ }
+ catch (java.io.IOException ex) { + throw new System.IO.IOException(ex.Message, ex); + } + }
+#endif
+ internal void WritePlainImage(PlainImageCollection pic) {
+ if ((pic == null) || (pic.Count == 0))
+ return;
+
+ if (pic.Count == 1) {
+ WritePlainImage( pic[0] );
+ return;
+ }
+
+ try {
+ if (NativeWriter.canWriteSequence ()) {
+ NativeWriter.prepareWriteSequence (null);
+ for (int i=0; i < pic.Count; i++) {
+ imageio.IIOImage iio = GetIIOImageContainer( pic[i] );
+ NativeWriter.writeToSequence (iio, null);
+ }
+ NativeWriter.endWriteSequence ();
+ }
+ else
+ WritePlainImage( pic[0] );
+ }
+ catch (java.io.IOException ex) { + throw new System.IO.IOException(ex.Message, ex); + } + }
+
+ internal void WritePlainImage(PlainImage pi) {
+ try {
+ imageio.IIOImage iio = GetIIOImageContainer( pi );
+ WriteImage( iio );
+ }
+ catch (java.io.IOException ex) { + throw new System.IO.IOException(ex.Message, ex); + }
+ }
+
+ private void WriteImage(imageio.IIOImage iio) {
+ if (NativeStream == null)
+ throw new Exception("Output stream not specified");
+
+ NativeWriter.write( iio );
+ }
+
+ private imageio.IIOImage GetIIOImageContainer(PlainImage pi) {
+ java.util.ArrayList al = null;
+
+ // prepare thumbnails list
+ if (pi.Thumbnails != null) {
+ al = new java.util.ArrayList( pi.Thumbnails.Length );
+ for (int i=0; i < pi.Thumbnails.Length; i++)
+ al.add(pi.Thumbnails[i]);
+ }
+
+ // prepare IIOImage container
+ if (pi.NativeImage is image.BufferedImage) {
+ imageio.IIOImage iio = new javax.imageio.IIOImage(
+ (image.BufferedImage)pi.NativeImage, al, null /*pi.NativeMetadata*/);
+ return iio;
+ }
+ else
+ // TBD: This codec is for raster formats only
+ throw new NotSupportedException("Only raster formats are supported");
+ }
+
+
+ private imageio.metadata.IIOMetadata ReadImageMetadata(int frameIndex) {
+ if (NativeStream == null)
+ throw new Exception("Input stream not specified");
+
+ try {
+ imageio.metadata.IIOMetadata md = NativeReader.getImageMetadata( frameIndex );
+ return md;
+ }
+ catch (java.io.IOException ex) { + throw new System.IO.IOException(ex.Message, ex); + } + }
+
+ #endregion
+
+ #region Extra properties
+
+ public ImageFormat ImageFormat {
+ get { return _imageFormat; }
+ }
+
+ #endregion
+
+ #region Metadata parse
+
+ private float [] GetResolution(XmlDocument metaData) {
+ if (metaData == null)
+ return new float[]{0, 0};
+
+ ResolutionConfigurationCollection rcc = + (ResolutionConfigurationCollection) + ConfigurationSettings.GetConfig("system.drawing/codecsmetadata"); + + if (rcc == null) + throw new ConfigurationException("Configuration section codecsmetadata not found"); + + ResolutionConfiguration rc = rcc[ ImageFormat.ToString() ]; + + if (rc == null) + return new float[]{0, 0}; + + // Horizontal resolution + string xResPath = rc.XResPath; + string xRes; + + if (xResPath == string.Empty) + xRes = rc.XResDefault; + else + xRes = GetValueFromMetadata(metaData, xResPath); + + if ((xRes == null) || (xRes == string.Empty)) + xRes = rc.XResDefault; + + // Vertical resolution + string yResPath = rc.YResPath; + string yRes; + + if (yResPath == string.Empty) + yRes = rc.YResDefault; + else + yRes = GetValueFromMetadata(metaData, yResPath); + + if ((yRes == null) || (yRes == string.Empty)) + yRes = rc.YResDefault; + + // Resolution units + string resUnitsPath = rc.UnitsTypePath; + string resUnitsType; + + if (resUnitsPath == string.Empty) + resUnitsType = rc.UnitsTypeDefault; + else + resUnitsType = GetValueFromMetadata(metaData, resUnitsPath); + + if (resUnitsType == null) + resUnitsType = rc.UnitsTypeDefault; + + // Unit scale + string unitScale = rc.UnitsScale[resUnitsType].ToString(); + + // Adjust resolution to its units + float [] res = new float[2]; + res[0] = ParseFloatValue(xRes) * ParseFloatValue(unitScale); + res[1] = ParseFloatValue(yRes) * ParseFloatValue(unitScale); + + return res; + }
+
+ private string GetValueFromMetadata(XmlDocument metaData, string path) {
+ XmlNode n = metaData.SelectSingleNode(path);
+ if (n == null)
+ return null;
+
+ return n.InnerText;
+ }
+
+ private XmlDocument ConvertImageMetadata(imageio.metadata.IIOMetadata metaData) {
+ string [] formatNames = metaData.getMetadataFormatNames(); + dom.Element rootNode = (dom.Element) metaData.getAsTree(formatNames[0]); + + XmlDocument _metadataDocument = new XmlDocument();
+ XmlConvert(rootNode, _metadataDocument);
+
+ return _metadataDocument;
+ }
+
+ private void XmlConvert(dom.Node jNode, XmlNode nNode) {
+ XmlDocument document = nNode.OwnerDocument;
+ if (document == null)
+ document = (XmlDocument)nNode;
+
+ XmlNode n = null;
+ switch (jNode.getNodeType()) {
+ case 1 :
+ n = document.CreateNode(XmlNodeType.Element, jNode.getNodeName(), jNode.getNamespaceURI());
+ break;
+
+ case 4 :
+ n = document.CreateNode(XmlNodeType.CDATA, jNode.getNodeName(), jNode.getNamespaceURI());
+ break;
+
+ default:
+ return;
+ }
+ //set value
+ n.InnerText = jNode.getNodeValue();
+ nNode.AppendChild( n );
+
+ //copy attributes
+ org.w3c.dom.NamedNodeMap nm = jNode.getAttributes();
+ for (int i=0; i<nm.getLength(); i++) {
+ XmlAttribute a = document.CreateAttribute( nm.item(i).getNodeName() );
+ a.Value = nm.item(i).getNodeValue();
+ n.Attributes.Append( a );
+ }
+
+ //copy childs
+ org.w3c.dom.NodeList nl = jNode.getChildNodes();
+ for (int i=0; i<nl.getLength(); i++) {
+ XmlConvert(nl.item(i), n);
+ }
+ }
+
+ protected virtual float ParseFloatValue(string strValue) {
+ try {
+ if ((strValue != null) && (strValue != "")) { + int dividerPos = strValue.IndexOf("/"); + + if (dividerPos < 0) { + return float.Parse(strValue); + } + else { + return float.Parse(strValue.Substring( 0, dividerPos )) / + float.Parse(strValue.Substring( dividerPos + 1 )); + } + }
+ return float.NaN;
+ }
+ catch (Exception) {
+ return float.NaN;
+ }
+ }
+
+ #endregion
+
+ #region IDisposable members
+
+ public void Dispose() {
+ if (NativeReader != null) {
+ NativeReader.dispose();
+ NativeReader = null;
+ }
+
+ if (NativeWriter != null) {
+ NativeWriter.dispose();
+ NativeWriter = null;
+ }
+ }
+
+ #endregion
+
+ }
+}
|