示例#1
0
        /// <summary>
        /// 從串流<see cref="System.IO.Stream"/>建立貼圖資源(非DDS)
        /// </summary>
        /// <param name="stream">串流</param>
        /// <param name="device">D3D Device</param>
        /// <param name="d3dContext">If a Direct3D 11 device context is provided and the current device supports it for the given pixel format, it will auto-generate mipmaps.</param>
        public static void CreateWICTextureFromStream(Device device, Stream stream, out Resource texture, out ShaderResourceView textureView, DeviceContext d3dContext = null)
        {
            texture     = null;
            textureView = null;
            Guid containerFormatGuid;

            if (stream.CanRead)
            {
                if (stream.Length < 104857600 && stream.Length >= 8)
                {
                    var temp = new byte[8];
                    stream.Read(temp, 0, 8);
                    stream.Seek(0, SeekOrigin.Begin);
                    // https://en.wikipedia.org/wiki/List_of_file_signatures
                    if (temp[0] == 0xFF && temp[1] == 0xD8 && temp[2] == 0xFF)
                    {
                        containerFormatGuid = ContainerFormatGuids.Jpeg;
                    }
                    else if (temp[0] == 0x89 && temp[1] == 0x50 && temp[2] == 0x4E && temp[3] == 0x47 && temp[4] == 0x0D && temp[5] == 0x0A && temp[6] == 0x1A && temp[7] == 0x0A)
                    {
                        containerFormatGuid = ContainerFormatGuids.Png;
                    }
                    else if (temp[0] == 0x42 && temp[1] == 0x4D)
                    {
                        containerFormatGuid = ContainerFormatGuids.Bmp;
                    }
                    else if (temp[0] == 0x47 && temp[1] == 0x49 && temp[2] == 0x46 && temp[3] == 0x38 && (temp[4] == 0x37 || temp[4] == 0x39) && temp[5] == 0x61)
                    {
                        containerFormatGuid = ContainerFormatGuids.Gif;
                    }
                    else
                    {
                        return;
                    }
                }

                using (var decoder = new BitmapDecoder(ImagingFactory, containerFormatGuid))
                    using (var wicstream = new WICStream(ImagingFactory, stream)) {
                        try {
                            decoder.Initialize(wicstream, DecodeOptions.CacheOnDemand);
                            using (var frame = decoder.GetFrame(0)) {
                                CreateWICTexture(device, d3dContext, frame,
                                                 0, ResourceUsage.Default, BindFlags.ShaderResource, CpuAccessFlags.None, ResourceOptionFlags.None, LoadFlags.Default,
                                                 out texture, out textureView);
                            }
                        } catch (SharpDXException e) {
                            System.Diagnostics.Debug.WriteLine(e.ToString());
                        }
                    }
            }
        }
示例#2
0
        /// <summary>
        /// Function to determine if this codec can read the file or not.
        /// </summary>
        /// <param name="stream">Stream used to read the file information.</param>
        /// <returns>
        /// TRUE if the codec can read the file, FALSE if not.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="stream"/> parameter is NULL (Nothing in VB.Net).</exception>
        /// <exception cref="System.IO.IOException">Thrown when the stream is write-only.
        /// <para>-or-</para>
        /// <para>Thrown when the stream cannot perform seek operations.</para>
        /// </exception>
        public override bool IsReadable(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if (!stream.CanRead)
            {
                throw new IOException(Resources.GORGFX_STREAM_READ_ONLY);
            }

            if (!stream.CanSeek)
            {
                throw new IOException(Resources.GORGFX_STREAM_EOF);
            }

            long position = stream.Position;

            try
            {
                // Get our WIC interface.
                // Wrap the stream so WIC doesn't mess up the position.
                var wrapperStream = new GorgonStreamWrapper(stream);

                using (var wic = new GorgonWICImage())
                {
                    using (var decoder = new BitmapDecoder(wic.Factory, SupportedFormat))
                    {
                        using (var wicStream = new WICStream(wic.Factory, wrapperStream))
                        {
                            try
                            {
                                decoder.Initialize(wicStream, DecodeOptions.CacheOnDemand);
                            }
                            catch (SharpDXException)
                            {
                                return(false);
                            }

                            // Only load supported WIC formats.
                            if (SupportedFormat != decoder.ContainerFormat)
                            {
                                return(false);
                            }

                            using (var frame = decoder.GetFrame(0))
                            {
                                Guid bestFormat;
                                var  settings = ReadMetaData(wic, decoder, frame, out bestFormat);

                                return(settings.Format != BufferFormat.Unknown);
                            }
                        }
                    }
                }
            }
            finally
            {
                stream.Position = position;
            }
        }
示例#3
0
        /// <summary>
        /// Function to read file meta data.
        /// </summary>
        /// <param name="stream">Stream used to read the metadata.</param>
        /// <returns>
        /// The image meta data as a <see cref="GorgonLibrary.Graphics.IImageSettings">IImageSettings</see> value.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="stream"/> parameter is NULL (Nothing in VB.Net).</exception>
        /// <exception cref="System.IO.IOException">Thrown when the stream is write-only.
        /// <para>-or-</para>
        /// <para>Thrown when the stream cannot perform seek operations.</para>
        /// </exception>
        /// <exception cref="System.IO.EndOfStreamException">Thrown when an attempt to read beyond the end of the stream is made.</exception>
        public override IImageSettings GetMetaData(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if (!stream.CanRead)
            {
                throw new IOException(Resources.GORGFX_STREAM_WRITE_ONLY);
            }

            if (!stream.CanSeek)
            {
                throw new IOException(Resources.GORGFX_STREAM_NO_SEEK);
            }

            long position = stream.Position;

            try
            {
                // Wrap the stream so WIC doesn't mess up the position.
                var wrapperStream = new GorgonStreamWrapper(stream);

                // Get our WIC interface.
                using (var wic = new GorgonWICImage())
                {
                    using (var decoder = new BitmapDecoder(wic.Factory, SupportedFormat))
                    {
                        using (var wicStream = new WICStream(wic.Factory, wrapperStream))
                        {
                            try
                            {
                                decoder.Initialize(wicStream, DecodeOptions.CacheOnDemand);
                            }
                            catch (SharpDXException)
                            {
                                throw new IOException(string.Format(Resources.GORGFX_IMAGE_FILE_INCORRECT_ENCODER, Codec));
                            }

                            using (var frame = decoder.GetFrame(0))
                            {
                                Guid bestFormat;
                                var  settings = ReadMetaData(wic, decoder, frame, out bestFormat);

                                if (settings.Format == BufferFormat.Unknown)
                                {
                                    throw new IOException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, settings.Format));
                                }

                                return(settings);
                            }
                        }
                    }
                }
            }
            finally
            {
                stream.Position = position;
            }
        }
示例#4
0
        /// <summary>
        /// Function to load an image from a stream.
        /// </summary>
        /// <param name="stream">Stream containing the data to load.</param>
        /// <param name="size">Size of the data to read, in bytes.</param>
        /// <returns>
        /// The image data that was in the stream.
        /// </returns>
        protected internal override GorgonImageData LoadFromStream(GorgonDataStream stream, int size)
        {
            GorgonImageData result = null;

            // Get our WIC interface.
            var wrapperStream = new GorgonStreamWrapper(stream);

            using (var wic = new GorgonWICImage())
            {
                using (var decoder = new BitmapDecoder(wic.Factory, SupportedFormat))
                {
                    using (var wicStream = new WICStream(wic.Factory, wrapperStream))
                    {
                        try
                        {
                            decoder.Initialize(wicStream, DecodeOptions.CacheOnDemand);
                        }
                        catch (SharpDXException)
                        {
                            // Repackage this exception to keep in line with our API.
                            throw new IOException(string.Format(Resources.GORGFX_IMAGE_FILE_INCORRECT_DECODER, Codec));
                        }

                        using (var frame = decoder.GetFrame(0))
                        {
                            Guid bestFormat;
                            var  settings = ReadMetaData(wic, decoder, frame, out bestFormat);

                            if (settings.Format == BufferFormat.Unknown)
                            {
                                throw new IOException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, settings.Format));
                            }

                            // Create our image data.
                            try
                            {
                                _actualArrayCount = settings.ArrayCount;
                                if (ArrayCount > 0)
                                {
                                    settings.ArrayCount = ArrayCount;
                                }

                                result = new GorgonImageData(settings);

                                if ((settings.ArrayCount > 1) && (_actualArrayCount > 1))
                                {
                                    ReadFrames(wic, result, decoder);
                                }
                                else
                                {
                                    ReadFrame(wic, result, frame.PixelFormat, bestFormat, frame);
                                }

                                // If we've not read the full length of the data (WIC seems to ignore the CRC on the IEND chunk for PNG files for example),
                                // then we need to move the pointer up by however many bytes we've missed.
                                if (wrapperStream.Position < size)
                                {
                                    wrapperStream.Position = size;
                                }
                            }
                            catch
                            {
                                // If we run into a problem, dump the memory buffer.
                                if (result != null)
                                {
                                    result.Dispose();
                                }

                                throw;
                            }
                        }
                    }
                }
            }

            return(result);
        }
示例#5
0
        /// <summary>
        /// Function to retrieve a list of frame delays for each frame in an animated GIF.
        /// </summary>
        /// <param name="stream">Stream containing the animated GIF.</param>
        /// <returns>
        /// An array of frame delays (1/100th of a second), or an empty array if the image is not an animated GIF.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="stream"/> parameter is NULL (Nothing in VB.Net).</exception>
        /// <exception cref="System.IO.IOException">Thrown when the stream parameter is write-only.
        /// <para>-or-</para>
        /// <para>The data in the stream could not be decoded as GIF file.</para>
        /// <para>-or-</para>
        /// <para>The stream cannot perform seek operations.</para>
        /// </exception>
        /// <exception cref="System.IO.EndOfStreamException">Thrown when an attempt to read beyond the end of the stream is made.</exception>
        public ushort[] GetFrameDelays(Stream stream)
        {
            var result = new ushort[0];

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if (!stream.CanRead)
            {
                throw new IOException(Resources.GORGFX_STREAM_WRITE_ONLY);
            }

            if (!stream.CanSeek)
            {
                throw new IOException(Resources.GORGFX_STREAM_NO_SEEK);
            }

            if (!UseAllFrames)
            {
                return(result);
            }

            long position = stream.Position;

            try
            {
                var wrapperStream = new GorgonStreamWrapper(stream);

                // Get our WIC interface.
                using (var wic = new GorgonWICImage())
                {
                    using (var decoder = new BitmapDecoder(wic.Factory, SupportedFormat))
                    {
                        using (var wicStream = new WICStream(wic.Factory, wrapperStream))
                        {
                            try
                            {
                                decoder.Initialize(wicStream, DecodeOptions.CacheOnDemand);
                            }
                            catch (DX.SharpDXException)
                            {
                                // Repackage the exception to keep in line with our API defintion.
                                throw new IOException(string.Format(Resources.GORGFX_IMAGE_FILE_INCORRECT_DECODER, Codec));
                            }

                            if (decoder.FrameCount < 2)
                            {
                                return(result);
                            }

                            result = new ushort[decoder.FrameCount];

                            for (int frame = 0; frame < result.Length; frame++)
                            {
                                using (var frameImage = decoder.GetFrame(frame))
                                {
                                    // Check to see if we can actually read this thing.
                                    if (frame == 0)
                                    {
                                        Guid           temp;
                                        IImageSettings settings = ReadMetaData(wic, decoder, frameImage, out temp);

                                        if (settings.Format == BufferFormat.Unknown)
                                        {
                                            throw new IOException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, settings.Format));
                                        }
                                    }

                                    using (var reader = frameImage.MetadataQueryReader)
                                    {
                                        var metaData = reader.GetMetadataByName("/grctlext/Delay");

                                        if (metaData != null)
                                        {
                                            result[frame] = (ushort)metaData;
                                        }
                                        else
                                        {
                                            result[frame] = 0;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                stream.Position = position;
            }

            return(result);
        }