Beispiel #1
0
        public static System.Drawing.Bitmap CreateBitmap(byte[] data, int width, int height, int pixelOffset)
        {
            int BlockSize = 8;

            int physicalWidth  = DXTUtility.GetBlockCount(width) * 4;
            int physicalHeight = DXTUtility.GetBlockCount(height) * 4;

            var pixels = new byte[physicalWidth * physicalHeight * 4];

            var blocks = DXTUtility.EnumerateBlocks(width, height, pixelOffset, BlockSize);

            foreach (var block in blocks)
            {
                // ここで block をデコードし pixel 配列の該当位置にRGBAデータを展開する
                ushort color0 = BinaryUtility.MakeUInt16(data, block.Offset);
                ushort color1 = BinaryUtility.MakeUInt16(data, block.Offset + 2);
                var    colors = new ColorRgba[4];

                if (color0 > color1)
                {
                    // アルファなし。使える色は4色
                    colors[0] = ColorRgba.FromRgb565(color0);                            // カラー0そのまま
                    colors[1] = ColorRgba.FromRgb565(color1);                            // カラー1そのまま
                    colors[2] = ColorRgba.Lerp(colors[0], colors[1], 1.0f / 3.0f);       // color_2 = 2/3*color_0 + 1/3*color_1
                    colors[3] = ColorRgba.Lerp(colors[0], colors[1], 2.0f / 3.0f);       // color_3 = 1/3*color_0 + 2/3*color_1
                }
                else
                {
                    // アルファあり。使える色は3色
                    colors[0] = ColorRgba.FromRgb565(color0);                            // カラー0そのまま
                    colors[1] = ColorRgba.FromRgb565(color1);                            // カラー1そのまま
                    colors[2] = ColorRgba.Lerp(colors[0], colors[1], 1.0f / 2.0f);       // color_2 = 1/2*color_0 + 1/2*color_1
                    colors[3] = new ColorRgba(0, 0, 0, 0);                               // 透明
                }

                uint indexBits = BinaryUtility.MakeUInt32(data, block.Offset + 4);

                for (int y = 0; y < 4; y++)
                {
                    for (int x = 0; x < 4; x++)
                    {
                        var idx = indexBits & 0x03;                   // インデックスの取り出し
                        var col = colors[idx];                        // カラーテーブルからインデックスでカラーを取り出す
                        int xx  = block.X + x;
                        int yy  = block.Y + y;
                        int p   = (xx + yy * physicalWidth) * 4;      // ピクセルの書き込み位置
                        pixels[p + 0] = (byte)(col.B * 255.0f);       // 青(0~255)
                        pixels[p + 1] = (byte)(col.G * 255.0f);       // 緑(0~255)
                        pixels[p + 2] = (byte)(col.R * 255.0f);       // 赤(0~255)
                        pixels[p + 3] = (byte)(col.A * 255.0f);       // アルファ(0~255)
                        indexBits   >>= 2;                            // インデックスを2ビット右シフトして次に備える
                    }
                }
            }
            return(CreateBitmap2(pixels, width, height, physicalWidth));
        }