Example #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));
        }
Example #2
0
        public static DdsSimpleFileInfo GetDdsInfo(byte[] data)
        {
            const int HeaderSize = 0x80;

            var info = new DdsSimpleFileInfo();    // 情報クラスを作成

            if (data.Length < HeaderSize)
            {
                return(info);        // DDSとしてのヘッダサイズが足りない
            }

            var magic = Encoding.UTF8.GetString(data, 0, 4);        // data 配列の先頭から連続する4バイトを文字列に変換

            if (magic != "DDS ")
            {
                return(info);        // DDSファイルではない
            }

            // 画像の横幅と高さ
            info.Height = (int)BinaryUtility.MakeUInt32(data, 0x0c); // data 配列の 12バイト目から連続する4バイトをInt32に変換
            info.Width  = (int)BinaryUtility.MakeUInt32(data, 0x10); // data 配列の 16バイト目から連続する4バイトをInt32に変換

            info.PixelOffset = HeaderSize;                           // ピクセルデータの開始位置

            // DXT1形式かどうかをチェック
            info.Format = Encoding.UTF8.GetString(data, 0x54, 4);
            var byte1 = data[0x54];
            var byte2 = data[0x55];
            var byte3 = data[0x56];
            var byte4 = data[0x57];

            switch (info.Format)
            {
            case "DXT1":
                break;

            default:
                return(info);
            }

            info.IsValid = true;            // ヘッダ取得成功を示すフラグを設定

            return(info);
        }