Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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.cs700
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
+
+ }
+}