Пример #1
0
        /// <summary>
        /// WIC <see cref="SharpDX.WIC.BitmapSource"/> から <see cref="SharpDX.Direct3D11.Texture2D"/> を作成する
        /// </summary>
        /// <param name="app"></param>
        /// <param name="bitmapSource">The WIC bitmap source</param>
        /// <param name="name">任意の名前</param>
        /// <returns>A Texture2D</returns>
        protected static MCTexture CreateTexture2DFromBitmap(Application app, SharpDX.WIC.BitmapSource bitmapSource, string name)
        {
            // WICイメージピクセルを受け取るためにDataStreamを割り当てます。
            int       stride = bitmapSource.Size.Width * 4;
            MCTexture tx     = new MCTexture(app, name);

            using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true))
            {
                // WICの内容をバッファにコピーする
                bitmapSource.CopyPixels(stride, buffer);
                Texture123DDesc d = new Texture123DDesc();
                d.D2 = new Texture2DDescription()
                {
                    Width             = bitmapSource.Size.Width,
                    Height            = bitmapSource.Size.Height,
                    ArraySize         = 1,
                    BindFlags         = SharpDX.Direct3D11.BindFlags.ShaderResource,
                    Usage             = SharpDX.Direct3D11.ResourceUsage.Immutable,
                    CpuAccessFlags    = SharpDX.Direct3D11.CpuAccessFlags.None,
                    Format            = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
                    MipLevels         = 1,
                    OptionFlags       = SharpDX.Direct3D11.ResourceOptionFlags.None,
                    SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                };
                if (tx.CreateTexture2D(0, d, new DataRectangle(buffer.DataPointer, stride)) == 1)
                {
                    return(null);
                }
            }
            return(tx);
        }
Пример #2
0
        private static Direct2D.Bitmap LoadFromFile(string filename, Direct2D.RenderTarget Direct2DTarget)
        {
            var factory = new WIC.ImagingFactory();
            // Decode image
            var decoder     = new WIC.BitmapDecoder(factory, filename, WIC.DecodeOptions.CacheOnLoad);
            var frameDecode = decoder.GetFrame(0);
            var source      = new WIC.BitmapSource(frameDecode.NativePointer);
            var fc          = new WIC.FormatConverter(factory);

            fc.Initialize(
                source,
                SharpDX.WIC.PixelFormat.Format32bppPBGRA,
                SharpDX.WIC.BitmapDitherType.None,
                null,
                0.0f,
                SharpDX.WIC.BitmapPaletteType.Custom
                );
            double dpX = 96.0f;
            double dpY = 96.0f;

            fc.GetResolution(out dpX, out dpY);
            Direct2D.BitmapProperties props = new Direct2D.BitmapProperties(
                new SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied));
            WIC.Bitmap bmp = new WIC.Bitmap(factory, fc, WIC.BitmapCreateCacheOption.CacheOnLoad);
            // Формируем изображения
            var Direct2DBitmap = SharpDX.Direct2D1.Bitmap.FromWicBitmap(Direct2DTarget, fc, props);

            // Cleanup
            factory.Dispose();
            decoder.Dispose();
            source.Dispose();
            fc.Dispose();
            return(Direct2DBitmap);
        }
Пример #3
0
 /// <summary>
 /// Creates a <see cref="SharpDX.Direct3D11.Texture2D"/> from a WIC <see cref="SharpDX.WIC.BitmapSource"/>
 /// </summary>
 /// <param name="device">The Direct3D11 device</param>
 /// <param name="bitmapSource">The WIC bitmap source</param>
 /// <returns>A Texture2D</returns>
 public static Texture2D CreateTexture2DFromBitmap(Device device, BitmapSource bitmapSource)
 {
     // Allocate DataStream to receive the WIC image pixels
         int stride = bitmapSource.Size.Width * 4;
         using (var buffer = new DataStream(bitmapSource.Size.Height * stride, true, true))
         {
         // Copy the content of the WIC to the buffer
         Rectangle rect = new Rectangle();
         var methods = bitmapSource.GetType().GetMethods();
         bitmapSource.GetType().GetMethods().First(item => item.Name == "CopyPixels").Invoke(bitmapSource, new object[] { stride, buffer });
           //  bitmapSource.CopyPixels(stride, buffer);
             return new Texture2D(device, new Texture2DDescription()
             {
                 Width = bitmapSource.Size.Width,
                 Height = bitmapSource.Size.Height,
                 ArraySize = 1,
                 BindFlags = BindFlags.ShaderResource,
                 Usage = ResourceUsage.Immutable,
                 CpuAccessFlags =CpuAccessFlags.None,
                 Format = Format.R8G8B8A8_UNorm,
                 MipLevels = 1,
                 OptionFlags = ResourceOptionFlags.None,
                 SampleDescription = new SampleDescription(1, 0),
             }, new DataRectangle(buffer.DataPointer, stride));
         }
 }
Пример #4
0
		public WICBitmapSourceImage (WIC.BitmapSource bmp, double scale, Direct2DFactories factories = null)
		{
			if (bmp == null)
				throw new ArgumentNullException ("bmp");
			this.bmp = bmp;
			this.scale = scale;
			this.factories = factories ?? Direct2DFactories.Shared;
		}
Пример #5
0
 public WICBitmapSourceImage(WIC.BitmapSource bmp, Direct2DFactories factories = null)
 {
     if (bmp == null)
     {
         throw new ArgumentNullException("bmp");
     }
     this.bmp       = bmp;
     this.factories = factories ?? Direct2DFactories.Shared;
 }
Пример #6
0
 /// <summary>
 /// Function to clip a bitmap.
 /// </summary>
 /// <param name="bitmap">Bitmap to clip.</param>
 /// <param name="buffer">Buffer containing clipped data.</param>
 private void ClipBitmap(WIC.BitmapSource bitmap, GorgonImageBuffer buffer)
 {
     using (var clipper = new WIC.BitmapClipper(Factory))
     {
         clipper.Initialize(bitmap, new DX.Rectangle(0, 0, buffer.Width < bitmap.Size.Width ? buffer.Width : bitmap.Size.Width,
                                                     buffer.Height < bitmap.Size.Height ? buffer.Height : bitmap.Size.Height));
         clipper.CopyPixels(buffer.PitchInformation.RowPitch, buffer.Data.BasePointer, buffer.PitchInformation.SlicePitch);
     }
 }
        /// <summary>
        /// Gets the bitmap.
        /// </summary>
        /// <param name="engineDevice">The engine device.</param>
        internal override D2D.Bitmap GetBitmap(EngineDevice engineDevice)
        {
            if (base.IsDisposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            D2D.Bitmap result = m_loadedBitmaps[engineDevice.DeviceIndex];
            if (result == null)
            {
                using (Stream inputStream = m_resourceLink.OpenInputStream())
                    using (WicBitmapSourceInternal bitmapSourceWrapper = GraphicsHelper.LoadBitmapSource_D2D(inputStream))
                    {
                        WIC.BitmapSource bitmapSource = bitmapSourceWrapper.Converter;

                        // Store common properties about the bitmap
                        if (!m_firstLoadDone)
                        {
                            m_firstLoadDone = true;
                            m_pixelWidth    = bitmapSource.Size.Width;
                            m_pixelHeight   = bitmapSource.Size.Height;
                            if (m_totalFrameCount > 1)
                            {
                                m_framePixelWidth  = m_pixelWidth / m_framesX;
                                m_framePixelHeight = m_pixelHeight / m_framesY;
                            }
                            else
                            {
                                m_framePixelWidth  = m_pixelWidth;
                                m_framePixelHeight = m_pixelHeight;
                            }
                            bitmapSource.GetResolution(out m_dpiX, out m_dpyY);
                        }

                        // Load the bitmap into Direct2D
                        result = D2D.Bitmap.FromWicBitmap(
                            engineDevice.FakeRenderTarget2D, bitmapSource,
                            new D2D.BitmapProperties(new D2D.PixelFormat(
                                                         SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                                                         D2D.AlphaMode.Premultiplied)));

                        // Register loaded bitmap
                        m_loadedBitmaps[engineDevice.DeviceIndex] = result;
                    }
            }


            return(result);
        }
Пример #8
0
        public IImage LoadImage(Stream stream)
        {
            var factories = Direct2DFactories.Shared;
            var d         = new WIC.BitmapDecoder(factories.WICFactory, stream, WIC.DecodeOptions.CacheOnDemand);

            WIC.BitmapSource b = d.GetFrame(0);

            var renderFormat = WIC.PixelFormat.Format32bppPBGRA;

            if (b.PixelFormat != renderFormat)
            {
                //System.Diagnostics.Debug.WriteLine ("BMP FORMAT: " + b.PixelFormat);
                var c = new WIC.FormatConverter(factories.WICFactory);
                c.Initialize(b, renderFormat);
                //System.Diagnostics.Debug.WriteLine ("CO  FORMAT: " + c.PixelFormat);
                b = c;
            }

            // Convert the BitmapSource to a Bitmap so we can allow the decoder to go out of memory
            return(new WICBitmapSourceImage(new WIC.Bitmap(factories.WICFactory, b, WIC.BitmapCreateCacheOption.CacheOnLoad), 1.0, factories));
        }
Пример #9
0
        /// <summary>
        /// Function to clip or scale the bitmap up or down to the size of the buffer.
        /// </summary>
        /// <param name="bitmap">Bitmap to scale.</param>
        /// <param name="filter">Filtering to apply to the scaled bitmap.</param>
        /// <param name="buffer">Buffer to receive the scaled bitmap.</param>
        /// <param name="clip">TRUE to clip, FALSE to scale.</param>
        /// <returns>TRUE if clipping/scaling was performed, FALSE if not.</returns>
        private bool ResizeBitmap(WIC.BitmapSource bitmap, WIC.BitmapInterpolationMode filter, GorgonImageBuffer buffer, bool clip)
        {
            if (!clip)
            {
                using (var scaler = new WIC.BitmapScaler(Factory))
                {
                    scaler.Initialize(bitmap, buffer.Width, buffer.Height, filter);
                    scaler.CopyPixels(buffer.PitchInformation.RowPitch, buffer.Data.BasePointer, buffer.PitchInformation.SlicePitch);
                }

                return(true);
            }

            if ((buffer.Width >= bitmap.Size.Width) && (buffer.Height >= bitmap.Size.Height))
            {
                return(false);
            }

            ClipBitmap(bitmap, buffer);
            return(true);
        }
        public static d2.Bitmap LoadBitmap(this d2.RenderTarget renderTarget, Stream stream)
        {
            var bitmapDecoder = new wic.BitmapDecoder(DXGraphicsService.FactoryImaging, stream,
                                                      wic.DecodeOptions.CacheOnDemand);

            wic.BitmapFrameDecode bitmapFrameDecode = bitmapDecoder.GetFrame(0);
            var bitmapSource = new wic.BitmapSource(bitmapFrameDecode.NativePointer);

            var formatConverter = new wic.FormatConverter(DXGraphicsService.FactoryImaging);

            formatConverter.Initialize(bitmapSource, wic.PixelFormat.Format32bppPBGRA);

            d2.Bitmap bitmap = d2.Bitmap.FromWicBitmap(renderTarget, formatConverter);

            formatConverter.Dispose();
            /* todo: check to see if I need to register to dispose of this later...  Can't comment this out because server side rendering will crash */
            //bitmapSource.Dispose();
            bitmapFrameDecode.Dispose();
            bitmapDecoder.Dispose();

            return(bitmap);
        }
        public static Texture2D CreateTex2DFromBitmap(SharpDX.WIC.BitmapSource bsource, SharpDX.Direct3D11.Device device)
        {
            Texture2DDescription desc;

            desc.Width                     = bsource.Size.Width;
            desc.Height                    = bsource.Size.Height;
            desc.ArraySize                 = 1;
            desc.BindFlags                 = BindFlags.ShaderResource;
            desc.Usage                     = ResourceUsage.Default;
            desc.CpuAccessFlags            = CpuAccessFlags.None;
            desc.Format                    = SharpDX.DXGI.Format.R8G8B8A8_UNorm;
            desc.MipLevels                 = 1;
            desc.OptionFlags               = ResourceOptionFlags.None;
            desc.SampleDescription.Count   = 1;
            desc.SampleDescription.Quality = 0;

            using (DataStream s = new DataStream(bsource.Size.Height * bsource.Size.Width * 4, true, true))
            {
                bsource.CopyPixels(bsource.Size.Width * 4, s);
                DataRectangle rect = new DataRectangle(s.DataPointer, bsource.Size.Width * 4);
                return(new Texture2D(device, desc, rect));
            }
        }
Пример #12
0
        public static D3D11.Texture2D CreateTexture2DFromBitmap(D3D11.Device device, WIC.BitmapSource bitmapSource)
        {
            // Allocate DataStream to receive the WIC image pixels
            int stride = bitmapSource.Size.Width * 4;

            using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true))
            {
                // Copy the content of the WIC to the buffer
                bitmapSource.CopyPixels(stride, buffer);
                return(new D3D11.Texture2D(device, new D3D11.Texture2DDescription()
                {
                    Width = bitmapSource.Size.Width,
                    Height = bitmapSource.Size.Height,
                    ArraySize = 1,
                    BindFlags = D3D11.BindFlags.ShaderResource,
                    Usage = D3D11.ResourceUsage.Immutable,
                    CpuAccessFlags = D3D11.CpuAccessFlags.None,
                    Format = DXGI.Format.R8G8B8A8_UNorm,
                    MipLevels = 1,
                    OptionFlags = D3D11.ResourceOptionFlags.None,
                    SampleDescription = new DXGI.SampleDescription(1, 0),
                }, new SharpDX.DataRectangle(buffer.DataPointer, stride)));
            }
        }
Пример #13
0
 public BblBitmapSource(SharpDX.WIC.BitmapSource source)
 {
     WICBitmapSource = source;
 }
Пример #14
0
        private async Task SetImageAsync(StorageFile file)
        {
            if (file == null)
            {
                return;
            }
            this.currentFile = file;

            //// カラマネする場合
            // モニタプロファイルのStreamを作成
            // ※物理モニタがない環境だと例外を吐く
            var profileStream = await DisplayInformation.GetForCurrentView().GetColorProfileAsync();

            // Stream → Bytes
            var profileBytes = new byte[profileStream.Size];
            var reader       = new DataReader(profileStream);
            await reader.LoadAsync((uint)profileStream.Size);

            reader.ReadBytes(profileBytes);

            // モニタプロファイルのColorContextを作成
            var factory        = new ImagingFactory(); // 割とあちこちで使う
            var displayProfile = new ColorContext(factory);

            displayProfile.InitializeFromMemory(DataStream.Create(profileBytes, true, false));

            using (var stream = await currentFile.OpenAsync(FileAccessMode.Read))
            {
                // デコーダーでファイルからフレームを取得
                var decoder = new BitmapDecoder(factory, stream.AsStream(), DecodeOptions.CacheOnDemand);
                if (decoder.FrameCount < 1)
                {
                    return;
                }
                var frame = decoder.GetFrame(0);

                // 埋め込みプロファイル取得
                var srcColorContexts      = frame.TryGetColorContexts(factory);
                var untaggedOrUnsupported = srcColorContexts == null || srcColorContexts.Length < 1;
                // プロファイルが読み込めなかった場合はsRGBとみなす
                var sourceProfile = !untaggedOrUnsupported ? srcColorContexts[0] : sRGBContext;

                SharpDX.WIC.BitmapSource transformSource = frame;
                if (untaggedOrUnsupported)
                {
                    // プロファイルが読み込めなかった場合はsRGBを適用したいので、FormatConverterで32bppPBGRAへ変換
                    // 変換しなかった場合、色変換時にCMYK画像をsRGBとして扱ってしまうことでエラーが発生する
                    var converter = new FormatConverter(factory);
                    converter.Initialize(frame, PixelFormat.Format32bppPBGRA);
                    transformSource = converter;
                }
                // ColorTransformを通すことで色変換ができる
                var transform = new ColorTransform(factory);
                transform.Initialize(transformSource, sourceProfile, displayProfile, PixelFormat.Format32bppPBGRA);

                var stride = transform.Size.Width * 4;    // 横1行のバイト数
                var size   = stride * transform.Size.Height;
                var bytes  = new byte[size];
                transform.CopyPixels(bytes, stride); // Byte配列にピクセルデータをコピー

                // ピクセルデータをWriteableBitmapに書き込み
                var bitmap = new WriteableBitmap(transform.Size.Width, transform.Size.Height);
                using (var s = bitmap.PixelBuffer.AsStream())
                {
                    await s.WriteAsync(bytes, 0, size);
                }

                this.Image1.Source = bitmap;
            }

            ////// カラマネしない場合
            //var bitmapImage = new BitmapImage();
            //var fileStream = await file.OpenStreamForReadAsync();
            //await bitmapImage.SetSourceAsync(fileStream.AsRandomAccessStream());
            //this.Image1.Source = bitmapImage;
        }
Пример #15
0
        /// <summary>
        /// Function to perform conversion/transformation of a bitmap.
        /// </summary>
        /// <param name="sourceData">WIC bitmap to transform.</param>
        /// <param name="destData">Destination data buffer.</param>
        /// <param name="rowPitch">Number of bytes per row in the image.</param>
        /// <param name="slicePitch">Number of bytes in total for the image.</param>
        /// <param name="destFormat">Destination format for transformation.</param>
        /// <param name="isSourcesRGB">TRUE if the source format is sRGB.</param>
        /// <param name="isDestsRGB">TRUE if the destination format is sRGB.</param>
        /// <param name="dither">Dithering to apply to images that get converted to a lower bit depth.</param>
        /// <param name="destRect">Rectangle containing the area to scale or clip</param>
        /// <param name="clip">TRUE to perform clipping instead of scaling.</param>
        /// <param name="scaleFilter">Filter to apply to scaled data.</param>
        public void TransformImageData(WIC.BitmapSource sourceData, IntPtr destData, int rowPitch, int slicePitch, Guid destFormat, bool isSourcesRGB, bool isDestsRGB, ImageDithering dither, Rectangle destRect, bool clip, ImageFilter scaleFilter)
        {
            WIC.BitmapSource    source        = sourceData;
            WIC.FormatConverter converter     = null;
            WIC.BitmapClipper   clipper       = null;
            WIC.BitmapScaler    scaler        = null;
            WIC.ColorContext    sourceContext = null;
            WIC.ColorContext    destContext   = null;
            WIC.ColorTransform  sRGBTransform = null;

            try
            {
                if (destFormat != Guid.Empty)
                {
                    if (sourceData.PixelFormat != destFormat)
                    {
                        converter = new WIC.FormatConverter(Factory);

                        if (!converter.CanConvert(sourceData.PixelFormat, destFormat))
                        {
                            throw new GorgonException(GorgonResult.FormatNotSupported,
                                                      string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, destFormat));
                        }

                        converter.Initialize(source, destFormat, (WIC.BitmapDitherType)dither, null, 0, WIC.BitmapPaletteType.Custom);
                        source = converter;
                    }

                    if ((isDestsRGB) ||
                        (isSourcesRGB))
                    {
                        sRGBTransform = new WIC.ColorTransform(Factory);
                        sourceContext = new WIC.ColorContext(Factory);
                        destContext   = new WIC.ColorContext(Factory);

                        sourceContext.InitializeFromExifColorSpace(isSourcesRGB ? 1 : 2);
                        destContext.InitializeFromExifColorSpace(isDestsRGB ? 1 : 2);

                        sRGBTransform.Initialize(source, sourceContext, destContext, destFormat);
                        source = sRGBTransform;
                    }
                }

                if (destRect.IsEmpty)
                {
                    source.CopyPixels(rowPitch, destData, slicePitch);
                    return;
                }

                Guid pixelFormat = source.PixelFormat;

                if (!clip)
                {
                    scaler = new WIC.BitmapScaler(Factory);
                    scaler.Initialize(source,
                                      destRect.Width,
                                      destRect.Height,
                                      (WIC.BitmapInterpolationMode)scaleFilter);
                    source = scaler;
                }
                else
                {
                    destRect.Width  = destRect.Width.Min(source.Size.Width);
                    destRect.Height = destRect.Height.Min(source.Size.Height);

                    if ((destRect.Width < source.Size.Width) ||
                        (destRect.Height < source.Size.Height))
                    {
                        clipper = new WIC.BitmapClipper(Factory);
                        clipper.Initialize(source,
                                           new DX.Rectangle(destRect.X, destRect.Y, destRect.Width, destRect.Height));
                        source     = clipper;
                        destRect.X = 0;
                        destRect.Y = 0;
                    }
                }

                // We have a change of format (probably due to the filter when scaling)... so we need to convert.
                if (source.PixelFormat != pixelFormat)
                {
                    converter = new WIC.FormatConverter(Factory);

                    if (!converter.CanConvert(source.PixelFormat, pixelFormat))
                    {
                        throw new GorgonException(GorgonResult.FormatNotSupported,
                                                  string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, pixelFormat));
                    }

                    converter.Initialize(source,
                                         pixelFormat,
                                         WIC.BitmapDitherType.None,
                                         null,
                                         0,
                                         WIC.BitmapPaletteType.Custom);
                    source = converter;
                }

                source.CopyPixels(rowPitch, destData, slicePitch);
            }
            finally
            {
                if (converter != null)
                {
                    converter.Dispose();
                }

                if (sourceContext != null)
                {
                    sourceContext.Dispose();
                }

                if (destContext != null)
                {
                    destContext.Dispose();
                }

                if (sRGBTransform != null)
                {
                    sRGBTransform.Dispose();
                }

                if (scaler != null)
                {
                    scaler.Dispose();
                }

                if (clipper != null)
                {
                    clipper.Dispose();
                }
            }
        }
Пример #16
0
        /// <summary>
        /// Function to convert the format of a bitmap into the format of the buffer.
        /// </summary>
        /// <param name="sourceFormat">Format to convert from.</param>
        /// <param name="destFormat">Format to convert into.</param>
        /// <param name="dithering">Dithering to apply.</param>
        /// <param name="filter">Filtering to apply to scaled bitmaps.</param>
        /// <param name="bitmap">Bitmap to convert.</param>
        /// <param name="bitmapPalette">Palette for the bitmap.</param>
        /// <param name="alphaValue">Value of pixel to consider transparent.</param>
        /// <param name="buffer">Buffer holding the converted data.</param>
        /// <param name="scale">TRUE to scale when converting, FALSE to keep at original size.</param>
        /// <param name="clip">TRUE to perform clipping, FALSE to keep at original size.</param>
        private void ConvertFormat(Guid sourceFormat, Guid destFormat, WIC.BitmapDitherType dithering,
                                   WIC.BitmapInterpolationMode filter, WIC.BitmapSource bitmap,
                                   WIC.Palette bitmapPalette, int alphaValue,
                                   GorgonImageBuffer buffer, bool scale, bool clip)
        {
            WIC.BitmapSource source       = bitmap;
            double           alphaPercent = alphaValue / 255.0;
            var paletteType = WIC.BitmapPaletteType.Custom;

            // If we have a palette, then confirm that the dithering method is valid.
            if (bitmapPalette != null)
            {
                // Do not apply dithering if we're using
                // a custom palette and request ordered dithering.
                switch (dithering)
                {
                case WIC.BitmapDitherType.Ordered4x4:
                case WIC.BitmapDitherType.Ordered8x8:
                case WIC.BitmapDitherType.Ordered16x16:
                    if (bitmapPalette.TypeInfo == WIC.BitmapPaletteType.Custom)
                    {
                        dithering = WIC.BitmapDitherType.None;
                    }
                    break;
                }
                paletteType = bitmapPalette.TypeInfo;
            }

            try
            {
                // Create a scaler if need one.
                if ((scale) && (!clip))
                {
                    var scaler = new WIC.BitmapScaler(Factory);
                    scaler.Initialize(bitmap, buffer.Width, buffer.Height, filter);
                    source = scaler;
                }

                // Create a clipper if we want to clip and the image needs resizing.
                if ((clip) && (scale) && ((buffer.Width < bitmap.Size.Width) || (buffer.Height < bitmap.Size.Height)))
                {
                    var clipper = new WIC.BitmapClipper(Factory);
                    clipper.Initialize(bitmap, new DX.Rectangle(0, 0, buffer.Width < bitmap.Size.Width ? buffer.Width : bitmap.Size.Width,
                                                                buffer.Height < bitmap.Size.Height ? buffer.Height : bitmap.Size.Height));
                    source = clipper;
                }

                using (var converter = new WIC.FormatConverter(Factory))
                {
                    if (!converter.CanConvert(sourceFormat, destFormat))
                    {
                        throw new GorgonException(GorgonResult.FormatNotSupported,
                                                  string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, buffer.Format));
                    }

                    converter.Initialize(source, destFormat, dithering, bitmapPalette, alphaPercent, paletteType);

                    if (!scale)
                    {
                        int rowPitch   = (GetBitsPerPixel(destFormat) * bitmap.Size.Width + 7) / 8;
                        int slicePitch = rowPitch * bitmap.Size.Height;

                        if ((rowPitch != buffer.PitchInformation.RowPitch) || (slicePitch != buffer.PitchInformation.SlicePitch))
                        {
                            throw new GorgonException(GorgonResult.CannotWrite, Resources.GORGFX_IMAGE_PITCH_TOO_SMALL);
                        }
                    }
                    converter.CopyPixels(buffer.PitchInformation.RowPitch, buffer.Data.BasePointer, buffer.PitchInformation.SlicePitch);
                }
            }
            finally
            {
                if (source != bitmap)
                {
                    source.Dispose();
                }
            }
        }