Example #1
0
        /// <summary>
        /// Query media informations.
        /// </summary>
        /// <param name="stream">
        /// A <see cref="Stream"/> where the media data is stored.
        /// </param>
        /// <param name="criteria">
        /// A <see cref="MediaCodecCriteria"/> that specify parameters for loading an media stream.
        /// </param>
        /// <returns>
        /// A <see cref="ImageInfo"/> containing information about the specified media.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="stream"/> or <paramref name="criteria"/> is null.
        /// </exception>
        public ImageInfo QueryInfo(Stream stream, MediaCodecCriteria criteria)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (criteria == null)
            {
                throw new ArgumentNullException("criteria");
            }

            ImageInfo info = new ImageInfo();

            using (System.Drawing.Bitmap iBitmap = new System.Drawing.Bitmap(stream)) {
                PixelLayout iBitmapPixelType;
                string      containerFormat;

                ConvertImageFormat(iBitmap.RawFormat, out containerFormat);
                ConvertPixelFormat(iBitmap, out iBitmapPixelType);

                info.ContainerFormat = containerFormat;
                info.PixelType       = iBitmapPixelType;
                info.Width           = (uint)iBitmap.Width;
                info.Height          = (uint)iBitmap.Height;
            }

            return(info);
        }
Example #2
0
        /// <summary>
        /// Save media to a <see cref="IO.Stream"/>.
        /// </summary>
        /// <param name="path">
        /// A <see cref="String"/> that specify the file path where media data is stored.
        /// </param>
        /// <param name="media">
        /// A <typeparamref name="TMedia"/> that holds the data to be stored.
        /// </param>
        /// <param name="format">
        /// A <see cref="String"/> that specify the media format to used for saving <paramref name="media"/>.
        /// </param>
        /// <param name="criteria">
        /// A <see cref="MediaCodecCriteria"/> that specify parameters for loading an image stream.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// This exception is thrown if at least one of the parameters <paramref name="path"/> or <paramref name="media"/>
        /// is null.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// This exception is thrown if no plugin cannot save the image <paramref name="media"/> on <paramref name="path"/>.
        /// </exception>
        public void Save(string path, TMedia media, string format, MediaCodecCriteria criteria)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            if (media == null)
            {
                throw new ArgumentNullException("media");
            }

            string tempMediaPath   = Path.GetTempFileName();
            bool   alreadyExisting = File.Exists(path);

            try {
                // Save media (on temporary file)
                using (FileStream fs = new FileStream(tempMediaPath, FileMode.Create, FileAccess.Write)) {
                    Save(fs, media, format, criteria);
                }
                // Place saved media
                if (alreadyExisting)
                {
                    File.Copy(tempMediaPath, path, true);                               // Copy existing file (overwriting)
                }
                else
                {
                    File.Move(tempMediaPath, path);                                             // Move temporary file
                }
            } catch {
                File.Delete(tempMediaPath);
                throw;
            }
        }
Example #3
0
        /// <summary>
        /// Load media from stream.
        /// </summary>
        /// <param name="stream">
        /// A <see cref="Stream"/> where the media data is stored.
        /// </param>
        /// <param name="format">
        /// The <see cref="String"/> which defines the format of the stream data.
        /// </param>
        /// <param name="criteria">
        /// A <see cref="MediaCodecCriteria"/> that specify parameters for loading an media stream.
        /// </param>
        /// <returns>
        /// An <typeparamref name="TMedia"/> holding the media data.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="stream"/> or <paramref name="criteria"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Exception thrown if <paramref name="stream"/> is not readable or seekable.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Exception thrown if no plugin is available for <paramref name="format"/> (filtered by
        /// <paramref name="criteria"/>) or all plugins are not able to load media from
        /// <paramref name="stream"/>.
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// Exception thrown if <paramref name="format"/> is not supported by any loaded plugin.
        /// </exception>
        public override Image Load(Stream stream, string format, MediaCodecCriteria criteria)
        {
            // Base implementation
            Image image = base.Load(stream, format, criteria);

            // Fix container format in MediaInformation
            image.MediaInformation.ContainerFormat = format;

            return(image);
        }
Example #4
0
        /// <summary>
        /// Load media from a local file.
        /// </summary>
        /// <param name="uri">
        /// A <see cref="String"/> that specify the resource path where the media data is stored.
        /// </param>
        /// <param name="format">
        /// The <see cref="String"/> which defines the format of the stream data.
        /// </param>
        /// <param name="criteria">
        /// A <see cref="MediaCodecCriteria"/> that specify parameters for loading an media stream.
        /// </param>
        /// <returns>
        /// An <typeparamref name="TMedia"/> holding the media data.
        /// </returns>
        public TMedia Load(string uri, string format, MediaCodecCriteria criteria)
        {
            if (uri == null)
            {
                throw new ArgumentNullException("uri");
            }

            using (MediaStream ms = new MediaStream(uri, FileMode.Open, FileAccess.Read)) {
                return(Load(ms, format, criteria));
            }
        }
Example #5
0
        /// <summary>
        /// Query media informations.
        /// </summary>
        /// <param name="path">
        /// A <see cref="String"/> that specify the file path where media data is stored.
        /// </param>
        /// <param name="criteria">
        /// A <see cref="MediaCodecCriteria"/> that specify parameters for loading an media stream.
        /// </param>
        /// <returns>
        /// A <typeparamref name="TMediaInfo"/> containing information about the specified media.
        /// </returns>
        public TMediaInfo QueryInfo(string path, MediaCodecCriteria criteria)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            if (criteria == null)
            {
                throw new ArgumentNullException("criteria");
            }

            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) {
                return(QueryInfo(fs, criteria));
            }
        }
Example #6
0
        /// <summary>
        /// Query media informations.
        /// </summary>
        /// <param name="stream">
        /// A <see cref="Stream"/> where the media data is stored.
        /// </param>
        /// <param name="criteria">
        /// A <see cref="MediaCodecCriteria"/> that specify parameters for loading an media stream.
        /// </param>
        /// <returns>
        /// A <typeparamref name="TMediaInfo"/> containing information about the specified media.
        /// </returns>
        public TMediaInfo QueryInfo(Stream stream, MediaCodecCriteria criteria)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (stream.CanRead == false)
            {
                throw new ArgumentException(String.Format("unable to read from stream"));
            }
            if (stream.CanSeek == false)
            {
                throw new ArgumentException(String.Format("stream is not seekable"));
            }
            if (criteria == null)
            {
                throw new ArgumentNullException("criteria");
            }

            List <TPlugin> supportedPlugins = Plugins;

            // Class filtering
            if (supportedPlugins != null)
            {
                supportedPlugins = FilterReadPlugins(supportedPlugins, criteria);
            }
            if (supportedPlugins == null)
            {
                throw new InvalidOperationException("no plugin available");
            }

            foreach (TPlugin plugin in supportedPlugins)
            {
                try {
                    // Rewind stream
                    if (stream.CanSeek)
                    {
                        stream.Seek(0, SeekOrigin.Begin);
                    }
                    // Try to get information
                    return(plugin.QueryInfo(stream, criteria));
                } catch {
                }
            }

            // Don't returns not assigned information
            throw new InvalidOperationException(String.Format("no plugin can query information on media"));
        }
Example #7
0
        /// <summary>
        /// Load media from a local file.
        /// </summary>
        /// <param name="uri">
        /// A <see cref="String"/> that specify the resource path where the media data is stored.
        /// </param>
        /// <param name="criteria">
        /// A <see cref="MediaCodecCriteria"/> that specify parameters for loading an media stream.
        /// </param>
        /// <returns>
        /// An <typeparamref name="TMedia"/> holding the media data.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// Eception thrown if no media plugin can open <paramref name="uri"/>.
        /// </exception>
        public TMedia Load(string uri, MediaCodecCriteria criteria)
        {
            if (uri == null)
            {
                throw new ArgumentNullException("uri");
            }

            foreach (string format in GetFormatsFromUrl(uri))
            {
                using (MediaStream ms = new MediaStream(uri, FileMode.Open, FileAccess.Read)) {
                    return(Load(ms, format, criteria));
                }
            }

            throw new InvalidOperationException(String.Format("no format recognized from URI \"{0}\"", uri));
        }
Example #8
0
        /// <summary>
        /// Query media informations.
        /// </summary>
        /// <param name="uri">
        /// A <see cref="Uri"/> that specify the resource location where media data is stored.
        /// </param>
        /// <param name="criteria">
        /// A <see cref="MediaCodecCriteria"/> that specify parameters for loading an media stream.
        /// </param>
        /// <returns>
        /// A <typeparamref name="TMediaInfo"/> containing information about the specified media.
        /// </returns>
        public TMediaInfo QueryInfo(Uri uri, MediaCodecCriteria criteria)
        {
            if (uri == null)
            {
                throw new ArgumentNullException("uri");
            }
            if (criteria == null)
            {
                throw new ArgumentNullException("criteria");
            }

            string localPath = GetLocalUriPath(uri);

            using (FileStream fs = new FileStream(localPath, FileMode.Open, FileAccess.Read)) {
                return(QueryInfo(fs, criteria));
            }
        }
Example #9
0
        /// <summary>
        /// Filters the plugins (used for reading) by criteria.
        /// </summary>
        /// <returns>
        /// The read plugins.
        /// </returns>
        /// <param name='plugins'>
        /// The actual plugin list.
        /// </param>
        /// <param name='criteria'>
        /// Criteria.
        /// </param>
        /// <exception cref='ArgumentNullException'>
        /// Is thrown when an argument passed to a method is invalid because it is <see langword="null" /> .
        /// </exception>
        protected virtual List <TPlugin> FilterWritePlugins(List <TPlugin> plugins, MediaCodecCriteria criteria)
        {
            if (plugins == null)
            {
                throw new ArgumentNullException("plugins");
            }
            if (criteria == null)
            {
                throw new ArgumentNullException("criteria");
            }

            // Criteria: PluginName
            if (criteria.IsDefined(PluginName))
            {
                plugins = plugins.FindAll(delegate(TPlugin obj) {
                    return(obj.Name == (string)criteria[PluginName]);
                });
            }

            return(plugins);
        }
Example #10
0
        /// <summary>
        /// Load media from stream.
        /// </summary>
        /// <param name="stream">
        /// A <see cref="Stream"/> where the media data is stored.
        /// </param>
        /// <param name="format">
        /// The <see cref="String"/> which defines the format of the stream data.
        /// </param>
        /// <param name="criteria">
        /// A <see cref="MediaCodecCriteria"/> that specify parameters for loading an media stream.
        /// </param>
        /// <returns>
        /// An <typeparamref name="TMedia"/> holding the media data.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="stream"/> or <paramref name="criteria"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Exception thrown if <paramref name="stream"/> is not readable or seekable.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Exception thrown if no plugin is available for <paramref name="format"/> (filtered by
        /// <paramref name="criteria"/>) or all plugins are not able to load media from
        /// <paramref name="stream"/>.
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// Exception thrown if <paramref name="format"/> is not supported by any loaded plugin.
        /// </exception>
        public virtual TMedia Load(Stream stream, string format, MediaCodecCriteria criteria)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (criteria == null)
            {
                throw new ArgumentNullException("criteria");
            }
            if (stream.CanRead == false)
            {
                throw new ArgumentException("unable to read from stream");
            }

            List <TPlugin> supportedPlugins = Plugins;

            // Format filtering
            if (supportedPlugins != null)
            {
                supportedPlugins = FilterReadPlugins(supportedPlugins, format);
            }
            if ((supportedPlugins == null) || (supportedPlugins.Count == 0))
            {
                throw new NotSupportedException(String.Format("format {0} is not supported", format));
            }
            // Class filtering
            supportedPlugins = FilterReadPlugins(supportedPlugins, criteria);
            if ((supportedPlugins == null) || (supportedPlugins.Count == 0))
            {
                throw new InvalidOperationException("no plugin available");
            }

            StringBuilder exceptionMessage = new StringBuilder();

            foreach (TPlugin plugin in supportedPlugins)
            {
                try {
                    // Rewind stream
                    if (stream.CanSeek)
                    {
                        stream.Seek(0, SeekOrigin.Begin);
                    }
                    // Try to get information
                    return(plugin.Load(stream, criteria));
                } catch (Exception exception) {
                    if (supportedPlugins.Count > 1)
                    {
                        exceptionMessage.AppendLine(String.Format("- '{0}' exception: {1};", plugin.Name, exception.Message));
                        continue;
                    }

                    throw new InvalidOperationException(String.Format("no plugin can load media: {0}", exception.Message));
                }
            }

            // Remove trailing carriage return.
            exceptionMessage = exceptionMessage.Remove(exceptionMessage.Length - 1, 1);
            // Don't returns not assigned information
            throw new InvalidOperationException(String.Format("no plugin can load media; the reasons are:\n{0}", exceptionMessage));
        }
Example #11
0
        /// <summary>
        /// Save media to a <see cref="IO.Stream"/>.
        /// </summary>
        /// <param name="stream">
        /// A <see cref="IO.Stream"/> that stores the media data.
        /// </param>
        /// <param name="media">
        /// A <typeparamref name="TMedia"/> that holds the data to be stored.
        /// </param>
        /// <param name="format">
        /// A <see cref="String"/> that specify the media format to used for saving <paramref name="media"/>.
        /// </param>
        /// <param name="criteria">
        /// A <see cref="MediaCodecCriteria"/> that specify parameters for loading an image stream.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// This exception is thrown if at least one of the parameters <paramref name="stream"/> or <paramref name="media"/>
        /// is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// This exception is thrown if <paramref name="stream"/> cannot be seek or cannot be written.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// This exception is thrown if no plugin cannot save the media <paramref name="media"/> on the stream <paramref name="stream"/>.
        /// </exception>
        public void Save(Stream stream, TMedia media, string format, MediaCodecCriteria criteria)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (media == null)
            {
                throw new ArgumentNullException("media");
            }
            if (stream.CanWrite == false)
            {
                throw new ArgumentException(String.Format("unable to write to stream"));
            }
            if (stream.CanSeek == false)
            {
                throw new ArgumentException(String.Format("unable to seek on stream"));
            }

            List <TPlugin> supportedPlugins = Plugins;

            // Format filtering
            if (supportedPlugins != null)
            {
                supportedPlugins = FilterWritePlugins(supportedPlugins, format);
            }
            if (supportedPlugins == null)
            {
                throw new NotSupportedException(String.Format("format {0} is not supported", format));
            }
            // Class filtering
            if (criteria != null)
            {
                supportedPlugins = FilterWritePlugins(supportedPlugins, criteria);
            }
            if (supportedPlugins == null)
            {
                throw new InvalidOperationException("no plugin available");
            }

            StringBuilder pluginLog = new StringBuilder();

            // Write image pixel data
            foreach (TPlugin plugin in supportedPlugins)
            {
                try {
                    // Position file cursor at beginning
                    if (stream.CanSeek)
                    {
                        stream.Seek(0, SeekOrigin.Begin);
                    }
                    // Save image pixel data
                    plugin.Save(stream, media, format, criteria);
                    return;
                } catch (Exception exception) {
                    pluginLog.AppendLine(String.Format("- Exception of plugin '{0}': {1}", plugin.Name, exception.Message));
                }
            }

            throw new InvalidOperationException(String.Format("no plugin can save media. Detailed information:\n{0}", pluginLog));
        }
Example #12
0
        /// <summary>
        /// Save media to stream.
        /// </summary>
        /// <param name="stream">
        /// A <see cref="IO.Stream"/> which stores the media data.
        /// </param>
        /// <param name="image">
        /// A <see cref="Image"/> holding the data to be stored.
        /// </param>
        /// <param name="format">
        /// A <see cref="String"/> that specify the media format to used for saving <paramref name="image"/>.
        /// </param>
        /// <param name="criteria">
        /// A <see cref="MediaCodecCriteria"/> that specify parameters for loading an image stream.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="stream"/>, <paramref name="image"/> or <paramref name="criteria"/> is null.
        /// </exception>
        public void Save(Stream stream, Image image, string format, MediaCodecCriteria criteria)
        {
            Bitmap iBitmap;

            System.Drawing.Imaging.ImageFormat iBitmapFormat;
            System.Drawing.Imaging.PixelFormat iBitmapPixelFormat;
            int iBitmapFlags;

            ConvertImageFormat(format, out iBitmapFormat);
            ConvertPixelFormat(image.PixelLayout, out iBitmapPixelFormat, out iBitmapFlags);

            // Obtain source and destination data pointers
            using (iBitmap = new Bitmap((int)image.Width, (int)image.Height, iBitmapPixelFormat)) {
                BitmapData iBitmapData = null;
                IntPtr     imageData   = image.ImageBuffer;

                try {
                    iBitmapData = iBitmap.LockBits(new System.Drawing.Rectangle(0, 0, iBitmap.Width, iBitmap.Height), ImageLockMode.ReadOnly, iBitmap.PixelFormat);

                    // Copy Image data dst Bitmap
                    unsafe {
                        byte *hImageDataPtr     = (byte *)imageData.ToPointer();
                        byte *iBitmapDataPtr    = (byte *)iBitmapData.Scan0.ToPointer();
                        uint  hImageDataStride  = image.Stride;
                        uint  iBitmapDataStride = (uint)iBitmapData.Stride;

                        // .NET Image Library stores bitmap scan line data in memory padded dst 4 bytes boundaries
                        // .NET Image Library expect a bottom up image, so invert the scan line order

                        iBitmapDataPtr = iBitmapDataPtr + ((image.Height - 1) * iBitmapDataStride);

                        for (uint line = 0; line < image.Height; line++, hImageDataPtr += hImageDataStride, iBitmapDataPtr -= iBitmapDataStride)
                        {
                            Memory.MemoryCopy(iBitmapDataPtr, hImageDataPtr, hImageDataStride);
                        }
                    }
                } finally {
                    if (iBitmapData != null)
                    {
                        iBitmap.UnlockBits(iBitmapData);
                    }
                }

                // Save image with the specified format
                ImageCodecInfo encoderInfo = Array.Find(ImageCodecInfo.GetImageEncoders(), delegate(ImageCodecInfo item) {
                    return(item.FormatID == iBitmapFormat.Guid);
                });

                EncoderParameters encoderParams = null;

                try {
                    EncoderParameters  encoderInfoParamList = iBitmap.GetEncoderParameterList(encoderInfo.Clsid);
                    EncoderParameter[] encoderInfoParams    = encoderInfoParamList != null ? encoderInfoParamList.Param : null;
                    bool supportQuality = false;
                    int  paramsCount    = 0;

                    if (encoderInfoParams != null)
                    {
                        Array.ForEach(encoderInfoParams, delegate(EncoderParameter item) {
                            if (item.Encoder.Guid == Encoder.Quality.Guid)
                            {
                                supportQuality = true;
                                paramsCount++;
                            }
                        });
                    }

                    encoderParams = new EncoderParameters(paramsCount);

                    paramsCount = 0;
                    if (supportQuality)
                    {
                        encoderParams.Param[paramsCount++] = new EncoderParameter(Encoder.Quality, 100);
                    }
                } catch (Exception) {
                    // Encoder does not support parameters
                }

                iBitmap.Save(stream, encoderInfo, encoderParams);
            }
        }
Example #13
0
        /// <summary>
        /// Internal method for creating Image from Bitmap.
        /// </summary>
        /// <param name="bitmap">
        /// A <see cref="Drawing.Bitmap"/> to be converted into an <see cref="Image"/> instance.
        /// </param>
        /// <param name="criteria">
        /// A <see cref="MediaCodecCriteria"/> that specify image conversion criteria.
        /// </param>
        /// <returns>
        /// It returns a <see cref="Image"/> instance that's equivalent to <paramref name="bitmap"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="bitmap"/> or <see cref="criteria"/> is null.
        /// </exception>
        internal static Image LoadFromBitmap(System.Drawing.Bitmap bitmap, MediaCodecCriteria criteria)
        {
            if (bitmap == null)
            {
                throw new ArgumentNullException("bitmap");
            }
            if (criteria == null)
            {
                throw new ArgumentNullException("criteria");
            }

            PixelLayout pType, pConvType;

            // Allocate image raster
            ConvertPixelFormat(bitmap, out pType);

            // Check for hardware/software support
            if (Pixel.IsSupportedInternalFormat(pType) == false)
            {
                if (criteria.IsDefined(ImageCodecCriteria.SoftwareSupport) && ((bool)criteria[ImageCodecCriteria.SoftwareSupport]))
                {
                    // Pixel type not directly supported by hardware... try to guess suitable software conversion
                    pConvType = Pixel.GuessBestSupportedConvertion(pType);
                    if (pConvType == PixelLayout.None)
                    {
                        throw new InvalidOperationException(String.Format("pixel type {0} is not supported by hardware neither software", pType));
                    }
                }
                else
                {
                    throw new InvalidOperationException(String.Format("pixel type {0} is not supported by hardware", pType));
                }
            }
            else
            {
                pConvType = pType;
            }

            Image image = new Image(pType, (uint)bitmap.Width, (uint)bitmap.Height);

            switch (bitmap.PixelFormat)
            {
            case System.Drawing.Imaging.PixelFormat.Format1bppIndexed:
            case System.Drawing.Imaging.PixelFormat.Format4bppIndexed:
            case System.Drawing.Imaging.PixelFormat.Format8bppIndexed:
                if (Runtime.RunningMono)
                {
                    // Bug 676362 - Bitmap Clone does not format return image to requested PixelFormat
                    // https://bugzilla.novell.com/show_bug.cgi?id=676362
                    //
                    // ATM no mono version has resolved the bug; current workaround is performing image
                    // sampling pixel by pixel, using internal conversion routines, even if it is very slow

                    LoadBitmapByPixel(bitmap, image);
                }
                else
                {
                    LoadBitmapByClone(bitmap, image);
                }
                break;

            default:
                LoadBitmapByLockBits(bitmap, image);
                break;
            }

            // ConvertItemType image to supported format, if necessary
            if ((pConvType != PixelLayout.None) && (pConvType != pType))
            {
                image = image.Convert(pConvType);
            }

            return(image);
        }