示例#1
0
        private static Bitmap parseEntry(BCHTexture bchtex, byte[] data)
        {
            Bitmap img = new Bitmap(1, 1);

            if (bchtex.Format >= 0 && bchtex.Format < 0xB)
            {
                img = getIMG(bchtex, data);
            }
            else if (bchtex.Format == 0xB || bchtex.Format == 0xC || bchtex.Format == 0xD)
            {
                img = getIMG_ETC1(bchtex, data);
            }

            /*if (CHK_FLIPVERT.Checked)
             * {
             *  img.RotateFlip(RotateFlipType.RotateNoneFlipY);
             * }*/
            return(img);
        }
示例#2
0
        public static BCH analyze(string path, byte[] input)
        {
            BCH bch = new BCH
            {
                FileName  = Path.GetFileNameWithoutExtension(path),
                FilePath  = Path.GetDirectoryName(path),
                Extension = Path.GetExtension(path)
            };

            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    bw.Write(input);
                    using (BinaryReader br = new BinaryReader(ms))
                    {
                        br.BaseStream.Seek(0, SeekOrigin.Begin);
                        long bchlength = br.BaseStream.Length;
                        bch.Magic = br.ReadUInt32();            //0x00 [4]byte        "BCH\x00"
                        br.ReadUInt32();                        //0x04 [4]byte        07 07 0D 97
                        bch.InfoOffset   = br.ReadUInt32();     //0x08 InfoTable Offset
                        bch.SymbolOffset = br.ReadUInt32();     //0x0C SymbTable Offset
                        bch.DescOffset   = br.ReadUInt32();     //0x10 DescTable Offset
                        bch.DataOffset   = br.ReadUInt32();     //0x14 DataTable Offset
                        uint AfterDataOffset = br.ReadUInt32(); //0x18 UnknTable offset
                        uint AADP            = br.ReadUInt32(); //0x1C InfoTable size
                        uint SymbSize        = br.ReadUInt32(); //0x20 SymbTable Size
                        uint DescSize        = br.ReadUInt32(); //0x24 DescTable Size
                        bch.DataLength = br.ReadUInt32();       //0x28 DataTable Size
                        uint dumb = br.ReadUInt32();            //0x2C UnknTable Size
                        if (bch.InfoOffset == 0x44)
                        {
                            SymbSize       = DescSize;
                            bch.DataLength = Math.Max(dumb, Math.Max(AADP, AfterDataOffset) - bch.DataOffset);
                        }
                        br.BaseStream.Seek(bch.InfoOffset + 0x24, SeekOrigin.Begin);
                        bch.TableOffset  = br.ReadUInt32() + bch.InfoOffset; //info+0x24
                        bch.TextureCount = br.ReadUInt32();                  //info+0x28
                        bch.TexNames     = new List <String>();
                        bch.RawNames     = new Dictionary <int, string>();
                        br.BaseStream.Seek((bch.SymbolOffset), SeekOrigin.Begin);
                        int  ofs = 0;
                        uint ind = 0;
                        while (ind < SymbSize)
                        {
                            string curname = "";
                            byte   b       = br.ReadByte();
                            ind++;
                            while (b != 0)
                            {
                                curname = curname + (char)b;
                                b       = br.ReadByte();
                                ind++;
                            }
                            bch.RawNames.Add(ofs, curname);
                            ofs += curname.Length + 1;
                        }
                        bch.Textures = new List <BCHTexture>();

                        for (int i = 0; i < bch.TextureCount; i++)
                        {
                            BCHTexture CurTexture = new BCHTexture();
                            br.BaseStream.Seek(bch.TableOffset + i * 0x4, SeekOrigin.Begin);
                            uint CurTexInfoOffset = br.ReadUInt32();
                            br.BaseStream.Seek(bch.InfoOffset + CurTexInfoOffset, SeekOrigin.Begin);
                            CurTexture.DescOffset = br.ReadUInt32() + bch.DescOffset; //0x0  Location within Desc
                            br.ReadUInt32();                                          //0x4  unk
                            br.ReadUInt32();                                          //0x8  unk
                            br.ReadUInt32();                                          //0xC  unk
                            br.ReadUInt32();                                          //0x10 unk
                            br.ReadUInt32();                                          //0x14 unk
                            br.ReadUInt32();                                          //0x18 unk;
                            int key = (int)br.ReadUInt32();                           //0x1C Name offset; not useful because we already parsed
                            if (bch.InfoOffset == 0x44)
                            {
                                // key--;
                            }
                            string name;
                            bch.RawNames.TryGetValue(key, out name);
                            bch.TexNames.Add(name);
                            br.BaseStream.Seek(CurTexture.DescOffset, SeekOrigin.Begin);
                            CurTexture.Height = br.ReadUInt16();     //0x0 height
                            CurTexture.Width  = br.ReadUInt16();     //0x2 width
                            br.ReadUInt32();                         //0x4, unk
                            CurTexture.DataOffset = br.ReadUInt32(); //0x8 DataOffset
                            br.ReadUInt32();                         //0xC unk
                            CurTexture.Format = br.ReadUInt32();     //0x10 Format
                            if (bch.InfoOffset == 0x44 || bch.InfoOffset == 0x3C)
                            {
                                CurTexture.DataOffset = CurTexture.Format;
                                br.ReadUInt32();
                                CurTexture.Format = br.ReadUInt32();
                            }
                            bch.Textures.Add(CurTexture); //OKAY DONE
                        }
                        for (int i = 0; i < bch.Textures.Count - 1; i++)
                        {
                            BCHTexture bchtex = bch.Textures[i];
                            bchtex.Length = bch.Textures[i + 1].DataOffset - bch.Textures[i].DataOffset;
                            if (bch.InfoOffset == 0x44)
                            {
                                bchtex.Length = (uint)(FormatToBPP((int)bchtex.Format) * bchtex.Width * bchtex.Height);
                            }
                            bch.Textures[i] = bchtex;
                        }
                        if (bch.TextureCount > 0)
                        {
                            BCHTexture bchtex1 = bch.Textures[bch.Textures.Count - 1];
                            bchtex1.Length = bch.DataLength - bchtex1.DataOffset;
                            if (bch.InfoOffset == 0x44)
                            {
                                bchtex1.Length = (uint)(FormatToBPP((int)bchtex1.Format) * bchtex1.Width * bchtex1.Height);
                            }
                            bch.Textures[bch.Textures.Count - 1] = bchtex1;
                        }
                        br.BaseStream.Seek(bch.DataOffset, SeekOrigin.Begin);
                        byte[] data = new byte[bch.DataLength];
                        br.Read(data, 0, (int)bch.DataLength);
                        bch.data = data;
                    }
                }
            }
            return(bch);
        }
示例#3
0
        private static Bitmap getIMG_ETC1(BCHTexture bchtex, byte[] data)
        {
            Bitmap img     = new Bitmap(Math.Max(nlpo2(bchtex.Width), 16), Math.Max(nlpo2(bchtex.Height), 16));
            string dllpath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location).Replace('\\', '/') + "/ETC1.dll";

            if (!File.Exists(dllpath))
            {
                File.WriteAllBytes(dllpath, Resources.ETC1);
            }
            try
            {
                /*
                 * Much of this code is taken/modified from Tharsis: http://jul.rustedlogic.net/thread.php?pid=436556#436556 Thank you to Tharsis's creator, xdaniel.
                 */
                byte[] temp = new byte[bchtex.Length];
                Array.Copy(data, bchtex.DataOffset, temp, 0, bchtex.Length);
                /* Get compressed data & handle to it */
                byte[] textureData = temp;
                //textureData = switchEndianness(textureData, 0x10);
                ushort[] input = new ushort[textureData.Length / sizeof(ushort)];
                Buffer.BlockCopy(textureData, 0, input, 0, textureData.Length);
                GCHandle pInput = GCHandle.Alloc(input, GCHandleType.Pinned);

                /* Marshal data around, invoke ETC1.dll for conversion, etc */
                UInt32 size1 = 0, size2 = 0;
                UInt16 wd = (ushort)img.Width, ht = (ushort)img.Height;
                ConvertETC1(IntPtr.Zero, ref size1, IntPtr.Zero, ref size2, wd, ht, bchtex.Format == 0xD || bchtex.Format == 0xB); //true = etc1a4, false = etc1
                uint[]   output  = new uint[size1];
                GCHandle pOutput = GCHandle.Alloc(output, GCHandleType.Pinned);
                ConvertETC1(pOutput.AddrOfPinnedObject(), ref size1, pInput.AddrOfPinnedObject(), ref size2, wd, ht, bchtex.Format == 0xD || bchtex.Format == 0xB);
                pOutput.Free();
                pInput.Free();

                /* Unscramble if needed // could probably be done in ETC1.dll, it's probably pretty damn ugly, but whatever... */
                /* Non-square code blocks could need some cleanup, verification, etc. as well... */
                uint[] finalized = new uint[output.Length];

                //Act if it's square because BCLIM swizzling is stupid
                Buffer.BlockCopy(output, 0, finalized, 0, finalized.Length);

                byte[] tmp = new byte[finalized.Length];
                Buffer.BlockCopy(finalized, 0, tmp, 0, tmp.Length);
                int    h       = img.Height;
                int    w       = img.Width;
                byte[] imgData = tmp;
                for (int i = 0; i < img.Width; i++)
                {
                    for (int j = 0; j < img.Height; j++)
                    {
                        int   k = (j + i * img.Height) * 4;
                        Color c = Color.FromArgb(imgData[k + 3], imgData[k], imgData[k + 1], imgData[k + 2]);
                        if (imgData[k] == imgData[k + 1] && imgData[k + 1] == imgData[k + 2] && imgData[k + 1] == 0)
                        {
                            if (imgData[k + 3] == 0)
                            {
                                c = Color.Transparent;
                            }
                        }
                        img.SetPixel(i, j, c);

                        /*if (bchtex.Format == 0xD)
                         * {
                         *  img.SetPixel(i, j, Color.FromArgb(0xFF, imgData[k], imgData[k + 1], imgData[k + 2]));
                         * }*/
                    }
                }
                //image is 13  instead of 12
                //         24             34
                img.RotateFlip(RotateFlipType.Rotate90FlipX);
                if (wd > ht)
                {
                    //image is now in appropriate order, but the shifting done been f****d up. Let's fix that.
                    Bitmap img2 = new Bitmap(Math.Max(nlpo2(bchtex.Width), 16), Math.Max(nlpo2(bchtex.Height), 16));
                    for (int y = 0; y < Math.Max(nlpo2(bchtex.Width), 16); y += 8)
                    {
                        for (int x = 0; x < Math.Max(nlpo2(bchtex.Height), 16); x++)
                        {
                            for (int j = 0; j < 8; j++)                            //treat every 8 vertical pixels as 1 pixel for purposes of calculation, add to offset later.
                            {
                                int x1 = (x + ((y / 8) * h)) % img2.Width;         //reshift x
                                int y1 = ((x + ((y / 8) * h)) / img2.Width) * 8;   //reshift y
                                img2.SetPixel(x1, y1 + j, img.GetPixel(x, y + j)); //reswizzle
                            }
                        }
                    }
                    return(img2);
                }
                else if (ht > wd)
                {
                    //image is now in appropriate order, but the shifting done been f****d up. Let's fix that.
                    Bitmap img2 = new Bitmap(Math.Max(nlpo2(bchtex.Width), 16), Math.Max(nlpo2(bchtex.Height), 16));
                    for (int y = 0; y < Math.Max(nlpo2(bchtex.Width), 16); y += 8)
                    {
                        for (int x = 0; x < Math.Max(nlpo2(bchtex.Height), 16); x++)
                        {
                            for (int j = 0; j < 8; j++)                            //treat every 8 vertical pixels as 1 pixel for purposes of calculation, add to offset later.
                            {
                                int x1 = x % img2.Width;                           //reshift x
                                int y1 = ((x + ((y / 8) * h)) / img2.Width) * 8;   //reshift y
                                img2.SetPixel(x1, y1 + j, img.GetPixel(x, y + j)); //reswizzle
                            }
                        }
                    }
                    return(img2);
                }
            }
            catch (IndexOutOfRangeException)
            {
                //
            }
            catch (AccessViolationException)
            {
                //
            }
            return(img);
        }
示例#4
0
        // Bitmap Data Writing
        private static Bitmap getIMG(BCHTexture bchtex, byte[] data)
        {
            // New Image
            Bitmap img  = new Bitmap(nlpo2(gcm(bchtex.Width, 8)), nlpo2(gcm(bchtex.Height, 8)));
            int    f    = (int)bchtex.Format;
            int    area = img.Width * img.Height;

            if (f == 0 && area > bchtex.Length / 4 || (f == 3 && area > bchtex.Length / 4))
            {
                img  = new Bitmap(gcm(bchtex.Width, 8), gcm(bchtex.Height, 8));
                area = img.Width * img.Height;
            }
            byte[] temp = new byte[(int)bchtex.Length];
            Array.Copy(data, bchtex.DataOffset, temp, 0, temp.Length);
            data = temp;
            // Coordinates
            // Colors
            // Tiles Per Width
            int p = gcm(img.Width, 8) / 8;

            if (p == 0)
            {
                p = 1;
            }
            // Build Image
            using (Stream BitmapStream = new MemoryStream(data))
                using (BinaryReader br = new BinaryReader(BitmapStream))
                    for (uint i = 0; i < area; i++) // for every pixel
                    {
                        uint x, y;
                        d2xy(i % 64, out x, out y);
                        uint tile = i / 64;

                        // Shift Tile Coordinate into Tilemap
                        x += (uint)(tile % p) * 8;
                        y += (uint)(tile / p) * 8;

                        // Get Color
                        Color c;
                        switch (f)
                        {
                        case 0: //RGBA8 - 4 bytes
                            c = DecodeColor(br.ReadUInt32(), f);
                            break;

                        case 1: //RGB8
                            byte[] data1 = br.ReadBytes(3); Array.Resize(ref data1, 4);
                            c = DecodeColor(BitConverter.ToUInt32(data1, 0), f);
                            break;

                        case 2: //RGBA5551
                        case 3: //RGB565
                        case 4: //RGBA4
                        case 5: //LA8
                            c = DecodeColor(br.ReadUInt16(), f);
                            break;

                        case 6: //HILO8
                        case 7: //L8
                        case 8: //A8
                        case 9: //LA4
                            c = DecodeColor(br.ReadByte(), f);
                            break;

                        case 0xA: //L4
                        case 0xB: //A4
                            uint val = br.ReadByte();
                            img.SetPixel((int)x, (int)y, DecodeColor(val & 0xF, f));
                            i++; x++;
                            c = DecodeColor(val >> 4, f);
                            break;

                        case 0xC:  // ETC1
                        case 0xD:  // ETC1A4
                        default:
                            throw new Exception("Invalid FileFormat.");
                        }
                        img.SetPixel((int)x, (int)y, c);
                    }
            return(img);
        }
示例#5
0
文件: BCH.cs 项目: SciresM/FEAT
        public static BCH analyze(string path, byte[] input)
        {
            BCH bch = new BCH
            {
                FileName = Path.GetFileNameWithoutExtension(path),
                FilePath = Path.GetDirectoryName(path),
                Extension = Path.GetExtension(path)
            };
            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    bw.Write(input);
                    using (BinaryReader br = new BinaryReader(ms))
                    {
                        br.BaseStream.Seek(0, SeekOrigin.Begin);
                        long bchlength = br.BaseStream.Length;
                        bch.Magic = br.ReadUInt32();          //0x00 [4]byte        "BCH\x00"
                        br.ReadUInt32();                      //0x04 [4]byte        07 07 0D 97
                        bch.InfoOffset = br.ReadUInt32();     //0x08 InfoTable Offset
                        bch.SymbolOffset = br.ReadUInt32();   //0x0C SymbTable Offset
                        bch.DescOffset = br.ReadUInt32();     //0x10 DescTable Offset
                        bch.DataOffset = br.ReadUInt32();     //0x14 DataTable Offset
                        uint AfterDataOffset = br.ReadUInt32();                      //0x18 UnknTable offset
                        uint AADP = br.ReadUInt32();                      //0x1C InfoTable size
                        uint SymbSize = br.ReadUInt32();                      //0x20 SymbTable Size
                        uint DescSize = br.ReadUInt32();                      //0x24 DescTable Size
                        bch.DataLength = br.ReadUInt32();                      //0x28 DataTable Size
                        uint dumb = br.ReadUInt32();                      //0x2C UnknTable Size
                        if (bch.InfoOffset == 0x44)
                        {
                            SymbSize = DescSize;
                            bch.DataLength = Math.Max(dumb, Math.Max(AADP, AfterDataOffset) - bch.DataOffset);
                        }
                        br.BaseStream.Seek(bch.InfoOffset + 0x24, SeekOrigin.Begin);
                        bch.TableOffset = br.ReadUInt32() + bch.InfoOffset; //info+0x24
                        bch.TextureCount = br.ReadUInt32(); //info+0x28
                        bch.TexNames = new List<String>();
                        bch.RawNames = new Dictionary<int, string>();
                        br.BaseStream.Seek((bch.SymbolOffset), SeekOrigin.Begin);
                        int ofs = 0;
                        uint ind = 0;
                        while (ind < SymbSize)
                        {
                            string curname = "";
                            byte b = br.ReadByte();
                            ind++;
                            while (b != 0)
                            {
                                curname = curname + (char)b;
                                b = br.ReadByte();
                                ind++;
                            }
                            bch.RawNames.Add(ofs, curname);
                            ofs += curname.Length + 1;
                        }
                        bch.Textures = new List<BCHTexture>();

                        for (int i = 0; i < bch.TextureCount; i++)
                        {
                            BCHTexture CurTexture = new BCHTexture();
                            br.BaseStream.Seek(bch.TableOffset + i * 0x4, SeekOrigin.Begin);
                            uint CurTexInfoOffset = br.ReadUInt32();
                            br.BaseStream.Seek(bch.InfoOffset + CurTexInfoOffset, SeekOrigin.Begin);
                            CurTexture.DescOffset = br.ReadUInt32() + bch.DescOffset; //0x0  Location within Desc
                            br.ReadUInt32();                   //0x4  unk
                            br.ReadUInt32();                   //0x8  unk
                            br.ReadUInt32();                   //0xC  unk
                            br.ReadUInt32();                   //0x10 unk
                            br.ReadUInt32();                   //0x14 unk
                            br.ReadUInt32(); //0x18 unk;
                            int key = (int)br.ReadUInt32(); //0x1C Name offset; not useful because we already parsed
                            if (bch.InfoOffset == 0x44)
                            {
                                // key--;
                            }
                            string name;
                            bch.RawNames.TryGetValue(key, out name);
                            bch.TexNames.Add(name);
                            br.BaseStream.Seek(CurTexture.DescOffset, SeekOrigin.Begin);
                            CurTexture.Height = br.ReadUInt16(); //0x0 height
                            CurTexture.Width = br.ReadUInt16(); //0x2 width
                            br.ReadUInt32(); //0x4, unk
                            CurTexture.DataOffset = br.ReadUInt32(); //0x8 DataOffset
                            br.ReadUInt32(); //0xC unk
                            CurTexture.Format = br.ReadUInt32(); //0x10 Format
                            if (bch.InfoOffset == 0x44 || bch.InfoOffset == 0x3C)
                            {
                                CurTexture.DataOffset = CurTexture.Format;
                                br.ReadUInt32();
                                CurTexture.Format = br.ReadUInt32();
                            }
                            bch.Textures.Add(CurTexture); //OKAY DONE

                        }
                        for (int i = 0; i < bch.Textures.Count - 1; i++)
                        {
                            BCHTexture bchtex = bch.Textures[i];
                            bchtex.Length = bch.Textures[i + 1].DataOffset - bch.Textures[i].DataOffset;
                            if (bch.InfoOffset == 0x44)
                            {
                                bchtex.Length = (uint)(FormatToBPP((int)bchtex.Format) * bchtex.Width * bchtex.Height);
                            }
                            bch.Textures[i] = bchtex;
                        }
                        if (bch.TextureCount > 0)
                        {
                            BCHTexture bchtex1 = bch.Textures[bch.Textures.Count - 1];
                            bchtex1.Length = bch.DataLength - bchtex1.DataOffset;
                            if (bch.InfoOffset == 0x44)
                            {
                                bchtex1.Length = (uint)(FormatToBPP((int)bchtex1.Format) * bchtex1.Width * bchtex1.Height);
                            }
                            bch.Textures[bch.Textures.Count - 1] = bchtex1;
                        }
                        br.BaseStream.Seek(bch.DataOffset, SeekOrigin.Begin);
                        byte[] data = new byte[bch.DataLength];
                        br.Read(data, 0, (int)bch.DataLength);
                        bch.data = data;
                    }
                }
            }
            return bch;
        }
示例#6
0
文件: BCH.cs 项目: SciresM/FEAT
 private static Bitmap parseEntry(BCHTexture bchtex, byte[] data)
 {
     Bitmap img = new Bitmap(1, 1);
     if (bchtex.Format >= 0 && bchtex.Format < 0xB)
     {
         img = getIMG(bchtex, data);
     }
     else if (bchtex.Format == 0xB || bchtex.Format == 0xC || bchtex.Format == 0xD)
     {
         img = getIMG_ETC1(bchtex, data);
     }
     /*if (CHK_FLIPVERT.Checked)
     {
         img.RotateFlip(RotateFlipType.RotateNoneFlipY);
     }*/
     return img;
 }
示例#7
0
文件: BCH.cs 项目: SciresM/FEAT
        private static Bitmap getIMG_ETC1(BCHTexture bchtex, byte[] data)
        {
            Bitmap img = new Bitmap(Math.Max(nlpo2(bchtex.Width), 16), Math.Max(nlpo2(bchtex.Height), 16));
            string dllpath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location).Replace('\\', '/') + "/ETC1.dll";
            if (!File.Exists(dllpath)) File.WriteAllBytes(dllpath, Resources.ETC1);
            try
            {
                /*
                 * Much of this code is taken/modified from Tharsis: http://jul.rustedlogic.net/thread.php?pid=436556#436556 Thank you to Tharsis's creator, xdaniel.
                 */
                byte[] temp = new byte[bchtex.Length];
                Array.Copy(data, bchtex.DataOffset, temp, 0, bchtex.Length);
                /* Get compressed data & handle to it */
                byte[] textureData = temp;
                //textureData = switchEndianness(textureData, 0x10);
                ushort[] input = new ushort[textureData.Length / sizeof(ushort)];
                Buffer.BlockCopy(textureData, 0, input, 0, textureData.Length);
                GCHandle pInput = GCHandle.Alloc(input, GCHandleType.Pinned);

                /* Marshal data around, invoke ETC1.dll for conversion, etc */
                UInt32 size1 = 0, size2 = 0;
                UInt16 wd = (ushort)img.Width, ht = (ushort)img.Height;
                ConvertETC1(IntPtr.Zero, ref size1, IntPtr.Zero, ref size2, wd, ht, bchtex.Format == 0xD || bchtex.Format == 0xB); //true = etc1a4, false = etc1
                uint[] output = new uint[size1];
                GCHandle pOutput = GCHandle.Alloc(output, GCHandleType.Pinned);
                ConvertETC1(pOutput.AddrOfPinnedObject(), ref size1, pInput.AddrOfPinnedObject(), ref size2, wd, ht, bchtex.Format == 0xD || bchtex.Format == 0xB);
                pOutput.Free();
                pInput.Free();

                /* Unscramble if needed // could probably be done in ETC1.dll, it's probably pretty damn ugly, but whatever... */
                /* Non-square code blocks could need some cleanup, verification, etc. as well... */
                uint[] finalized = new uint[output.Length];

                //Act if it's square because BCLIM swizzling is stupid
                Buffer.BlockCopy(output, 0, finalized, 0, finalized.Length);

                byte[] tmp = new byte[finalized.Length];
                Buffer.BlockCopy(finalized, 0, tmp, 0, tmp.Length);
                int h = img.Height;
                int w = img.Width;
                byte[] imgData = tmp;
                for (int i = 0; i < img.Width; i++)
                {
                    for (int j = 0; j < img.Height; j++)
                    {
                        int k = (j + i * img.Height) * 4;
                        Color c = Color.FromArgb(imgData[k + 3], imgData[k], imgData[k + 1], imgData[k + 2]);
                        if (imgData[k] == imgData[k + 1] && imgData[k + 1] == imgData[k + 2] && imgData[k + 1] == 0)
                        {
                            if (imgData[k + 3] == 0)
                            {
                                c = Color.Transparent;
                            }
                        }
                        img.SetPixel(i, j, c);
                        /*if (bchtex.Format == 0xD)
                        {
                            img.SetPixel(i, j, Color.FromArgb(0xFF, imgData[k], imgData[k + 1], imgData[k + 2]));
                        }*/
                    }
                }
                //image is 13  instead of 12
                //         24             34
                img.RotateFlip(RotateFlipType.Rotate90FlipX);
                if (wd > ht)
                {
                    //image is now in appropriate order, but the shifting done been f****d up. Let's fix that.
                    Bitmap img2 = new Bitmap(Math.Max(nlpo2(bchtex.Width), 16), Math.Max(nlpo2(bchtex.Height), 16));
                    for (int y = 0; y < Math.Max(nlpo2(bchtex.Width), 16); y += 8)
                    {
                        for (int x = 0; x < Math.Max(nlpo2(bchtex.Height), 16); x++)
                        {
                            for (int j = 0; j < 8; j++) //treat every 8 vertical pixels as 1 pixel for purposes of calculation, add to offset later.
                            {
                                int x1 = (x + ((y / 8) * h)) % img2.Width; //reshift x
                                int y1 = ((x + ((y / 8) * h)) / img2.Width) * 8; //reshift y
                                img2.SetPixel(x1, y1 + j, img.GetPixel(x, y + j)); //reswizzle
                            }
                        }
                    }
                    return img2;
                }
                else if (ht > wd)
                {
                    //image is now in appropriate order, but the shifting done been f****d up. Let's fix that.
                    Bitmap img2 = new Bitmap(Math.Max(nlpo2(bchtex.Width), 16), Math.Max(nlpo2(bchtex.Height), 16));
                    for (int y = 0; y < Math.Max(nlpo2(bchtex.Width), 16); y += 8)
                    {
                        for (int x = 0; x < Math.Max(nlpo2(bchtex.Height), 16); x++)
                        {
                            for (int j = 0; j < 8; j++) //treat every 8 vertical pixels as 1 pixel for purposes of calculation, add to offset later.
                            {
                                int x1 = x % img2.Width; //reshift x
                                int y1 = ((x + ((y / 8) * h)) / img2.Width) * 8; //reshift y
                                img2.SetPixel(x1, y1 + j, img.GetPixel(x, y + j)); //reswizzle
                            }
                        }
                    }
                    return img2;
                }
            }
            catch (IndexOutOfRangeException)
            {
                //
            }
            catch (AccessViolationException)
            {
                //
            }
            return img;
        }
示例#8
0
文件: BCH.cs 项目: SciresM/FEAT
        // Bitmap Data Writing
        private static Bitmap getIMG(BCHTexture bchtex, byte[] data)
        {
            // New Image
            Bitmap img = new Bitmap(nlpo2(gcm(bchtex.Width, 8)), nlpo2(gcm(bchtex.Height, 8)));
            int f = (int)bchtex.Format;
            int area = img.Width * img.Height;
            if (f == 0 && area > bchtex.Length / 4 || (f == 3 && area > bchtex.Length / 4))
            {
                img = new Bitmap(gcm(bchtex.Width, 8), gcm(bchtex.Height, 8));
                area = img.Width * img.Height;
            }
            byte[] temp = new byte[(int)bchtex.Length];
            Array.Copy(data, bchtex.DataOffset, temp, 0, temp.Length);
            data = temp;
            // Coordinates
            // Colors
            // Tiles Per Width
            int p = gcm(img.Width, 8) / 8;
            if (p == 0) p = 1;
            // Build Image
            using (Stream BitmapStream = new MemoryStream(data))
            using (BinaryReader br = new BinaryReader(BitmapStream))
                for (uint i = 0; i < area; i++) // for every pixel
                {
                    uint x, y;
                    d2xy(i % 64, out x, out y);
                    uint tile = i / 64;

                    // Shift Tile Coordinate into Tilemap
                    x += (uint)(tile % p) * 8;
                    y += (uint)(tile / p) * 8;

                    // Get Color
                    Color c;
                    switch (f)
                    {
                        case 0: //RGBA8 - 4 bytes
                            c = DecodeColor(br.ReadUInt32(), f);
                            break;
                        case 1: //RGB8
                            byte[] data1 = br.ReadBytes(3); Array.Resize(ref data1, 4);
                            c = DecodeColor(BitConverter.ToUInt32(data1, 0), f);
                            break;
                        case 2: //RGBA5551
                        case 3: //RGB565
                        case 4: //RGBA4
                        case 5: //LA8
                            c = DecodeColor(br.ReadUInt16(), f);
                            break;
                        case 6: //HILO8
                        case 7: //L8
                        case 8: //A8
                        case 9: //LA4
                            c = DecodeColor(br.ReadByte(), f);
                            break;
                        case 0xA: //L4
                        case 0xB: //A4
                            uint val = br.ReadByte();
                            img.SetPixel((int)x, (int)y, DecodeColor(val & 0xF, f));
                            i++; x++;
                            c = DecodeColor(val >> 4, f);
                            break;
                        case 0xC:  // ETC1
                        case 0xD:  // ETC1A4
                        default:
                            throw new Exception("Invalid FileFormat.");
                    }
                    img.SetPixel((int)x, (int)y, c);
                }
            return img;
        }