/// <summary>
        /// 指定された単色ビットマップ画像をDXT3テクスチャへ変換する
        /// </summary>
        /// <param name="source">変換元画像</param>
        /// <param name="color0">単色カラー</param>
        /// <returns>DXT3圧縮された画像</returns>
        public static Dxt3BitmapContent Compress(PixelBitmapContent <Color> source,
                                                 Color color0)
        {
            // DXT3ブロックデータを格納するためのバッファを確保
            byte[] outputData = new byte[source.Width * source.Height];

            // 単色カラーをBGR565に変換する
            ushort packedColor = new Bgr565(color0.ToVector3()).PackedValue;

            // 指定された画像を圧縮ブロック単位に処理をする
            int outputIndex = 0;

            for (int blockY = 0; blockY < source.Height; blockY += 4)
            {
                for (int blockX = 0; blockX < source.Width; blockX += 4)
                {
                    CompressDxt3Block(source, blockX, blockY, packedColor,
                                      outputData, outputIndex);
                    outputIndex += 16;
                }
            }

            // DXT3テクスチャの生成と圧縮したブロックデータの設定
            var result = new Dxt3BitmapContent(source.Width, source.Height);

            result.SetPixelData(outputData);

            return(result);
        }
        /// <summary>
        /// Converts a DigitalRune <see cref="Image"/> to an XNA <see cref="BitmapContent"/>.
        /// </summary>
        /// <param name="image">The <see cref="Image"/>.</param>
        /// <returns>The <see cref="BitmapContent"/>.</returns>
        public static BitmapContent ToContent(Image image)
        {
            BitmapContent content;

            switch (image.Format)
            {
            case DataFormat.R8G8B8A8_UNORM:
            case DataFormat.R8G8B8A8_UNORM_SRGB:
                content = new PixelBitmapContent <Color>(image.Width, image.Height);
                break;

            case DataFormat.B5G6R5_UNORM:
                content = new PixelBitmapContent <Bgr565>(image.Width, image.Height);
                break;

#if !MONOGAME
            case DataFormat.B5G5R5A1_UNORM:
                content = new PixelBitmapContent <Bgra5551>(image.Width, image.Height);
                break;
#endif
            case DataFormat.B4G4R4A4_UNORM:
                content = new PixelBitmapContent <Bgra4444>(image.Width, image.Height);
                break;

            case DataFormat.BC1_UNORM:
            case DataFormat.BC1_UNORM_SRGB:
                content = new Dxt1BitmapContent(image.Width, image.Height);
                break;

            case DataFormat.BC2_UNORM:
            case DataFormat.BC2_UNORM_SRGB:
                content = new Dxt3BitmapContent(image.Width, image.Height);
                break;

            case DataFormat.BC3_UNORM:
            case DataFormat.BC3_UNORM_SRGB:
                content = new Dxt5BitmapContent(image.Width, image.Height);
                break;

            case DataFormat.R8G8_SNORM:
                content = new PixelBitmapContent <NormalizedByte2>(image.Width, image.Height);
                break;

            case DataFormat.R8G8B8A8_SNORM:
                content = new PixelBitmapContent <NormalizedByte4>(image.Width, image.Height);
                break;

#if !MONOGAME
            case DataFormat.R10G10B10A2_UNORM:
                content = new PixelBitmapContent <Rgba1010102>(image.Width, image.Height);
                break;

            case DataFormat.R16G16_UNORM:
                content = new PixelBitmapContent <Rg32>(image.Width, image.Height);
                break;

            case DataFormat.R16G16B16A16_UNORM:
                content = new PixelBitmapContent <Rgba64>(image.Width, image.Height);
                break;

            case DataFormat.A8_UNORM:
            case DataFormat.R8_UNORM:
                content = new PixelBitmapContent <Alpha8>(image.Width, image.Height);
                break;
#endif
            case DataFormat.R32_FLOAT:
                content = new PixelBitmapContent <float>(image.Width, image.Height);
                break;

            case DataFormat.R32G32_FLOAT:
                content = new PixelBitmapContent <Vector2>(image.Width, image.Height);
                break;

            case DataFormat.R32G32B32A32_FLOAT:
                content = new PixelBitmapContent <Vector4>(image.Width, image.Height);
                break;

            case DataFormat.R16_FLOAT:
                content = new PixelBitmapContent <HalfSingle>(image.Width, image.Height);
                break;

            case DataFormat.R16G16_FLOAT:
                content = new PixelBitmapContent <HalfVector2>(image.Width, image.Height);
                break;

            case DataFormat.R16G16B16A16_FLOAT:
                content = new PixelBitmapContent <HalfVector4>(image.Width, image.Height);
                break;

#if MONOGAME
            case DataFormat.PVRTCI_2bpp_RGB:
                content = new PvrtcRgb2BitmapContent(image.Width, image.Height);
                break;

            case DataFormat.PVRTCI_4bpp_RGB:
                content = new PvrtcRgb4BitmapContent(image.Width, image.Height);
                break;

            case DataFormat.PVRTCI_2bpp_RGBA:
                content = new PvrtcRgba2BitmapContent(image.Width, image.Height);
                break;

            case DataFormat.PVRTCI_4bpp_RGBA:
                content = new PvrtcRgba4BitmapContent(image.Width, image.Height);
                break;

            case DataFormat.ETC1:
                content = new Etc1BitmapContent(image.Width, image.Height);
                break;

            //case DataFormat.ATC_RGB: Not supported in MonoGame.
            case DataFormat.ATC_RGBA_EXPLICIT_ALPHA:
                content = new AtcExplicitBitmapContent(image.Width, image.Height);
                break;

            case DataFormat.ATC_RGBA_INTERPOLATED_ALPHA:
                content = new AtcInterpolatedBitmapContent(image.Width, image.Height);
                break;
#endif

            default:
                string message = string.Format("The texture format {0} is not supported in MonoGame.", image.Format);
                throw new NotSupportedException(message);

                // Not supported:
                //  SurfaceFormat.HdrBlendable  // Only needed as render target format.
                //  SurfaceFormat.Bgr32         // Only used as WPF render target.
                //  SurfaceFormat.Bgra32        // Only used as WPF render target.
                //  SurfaceFormat.Dxt1a
            }

            Debug.Assert(content != null);
#if !MONOGAME
            // content.GetPixelData() is null in MonoGame.
            Debug.Assert(image.Data.Length == content.GetPixelData().Length);
#endif

            content.SetPixelData(image.Data);
            return(content);
        }