| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700 |
- 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
- }
- }
|