Ejemplo n.º 1
0
        public void Deserialize(Stream input)
        {
            ushort magic = input.ReadValueU16();

            if (magic != 512)
            {
                throw new FormatException();
            }

            this.Width  = input.ReadValueU16();
            this.Height = input.ReadValueU16();
            ushort mipCount = input.ReadValueU16();

            this.Flags  = input.ReadValueEnum <Tdx.HeaderFlags>();
            this.Format = input.ReadValueEnum <Tdx.D3DFormat>();

            if ((this.Flags & Tdx.HeaderFlags.HasExtraData) == Tdx.HeaderFlags.HasExtraData)
            {
                uint length = input.ReadValueU32();
                this.ExtraData = new byte[length];
                input.Read(this.ExtraData, 0, this.ExtraData.Length);
            }

            if ((this.Flags & Tdx.HeaderFlags.Unknown12) == Tdx.HeaderFlags.Unknown12)
            {
                // ref#5
                throw new FormatException();
            }
            else
            {
                if ((this.Flags & Tdx.HeaderFlags.Unknown0) == Tdx.HeaderFlags.Unknown0)
                {
                    // ref#6
                    throw new FormatException();
                }
                if ((this.Flags & Tdx.HeaderFlags.Unknown1) == Tdx.HeaderFlags.Unknown1)
                {
                    // ref#7
                    throw new FormatException();
                }

                if (this.Width > 2048 ||
                    this.Height > 2048)
                {
                    // ref#8
                    throw new FormatException();
                }

                this.Mipmaps.Clear();
                for (ushort i = 0; i < mipCount; i++)
                {
                    var mip = new Tdx.Mipmap();
                    mip.Width  = (ushort)Math.Max(1, this.Width >> i);
                    mip.Height = (ushort)Math.Max(1, this.Height >> i);
                    mip.Data   = new byte[Math.Max(1, GetMipSize(this.Format, mip.Width, mip.Height))];
                    input.Read(mip.Data, 0, mip.Data.Length);
                    this.Mipmaps.Add(mip);
                }
            }

            if (input.Position != input.Length)
            {
                throw new FormatException();
            }
        }
Ejemplo n.º 2
0
        public static void Main(string[] args)
        {
            bool showHelp  = false;
            bool saveExtra = false;

            var options = new OptionSet()
            {
                {
                    "e|extra",
                    "save extra data if present when converting from TDX",
                    v => saveExtra = v != null
                },
                {
                    "h|help",
                    "show this message and exit",
                    v => showHelp = v != null
                },
            };

            List <string> extra;

            try
            {
                extra = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (extra.Count < 1 || showHelp == true)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ input_texture*", GetExecutableName());
                Console.WriteLine("Convert a texture to / from Duels of the Planewalkers TDX format.");
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            foreach (string inputPath in extra)
            {
                Console.WriteLine(inputPath);

                var extension = Path.GetExtension(inputPath);
                if (extension != null)
                {
                    extension = extension.ToLowerInvariant();
                }

                // convert from tdx
                if (extension == ".tdx")
                {
                    Stream input = File.OpenRead(inputPath);
                    var    tdx   = new TdxFile();
                    tdx.Deserialize(input);
                    input.Close();

                    if (saveExtra == true && tdx.ExtraData != null)
                    {
                        using (var output = File.Create(Path.ChangeExtension(inputPath, "_extra.bin")))
                        {
                            output.Write(tdx.ExtraData, 0, tdx.ExtraData.Length);
                        }
                    }

                    if (tdx.Format == Tdx.D3DFormat.DXT1 ||
                        tdx.Format == Tdx.D3DFormat.DXT3 ||
                        tdx.Format == Tdx.D3DFormat.DXT5)
                    {
                        Native.Flags flags = 0;

                        if (tdx.Format == Tdx.D3DFormat.DXT1)
                        {
                            flags |= Native.Flags.DXT1;
                        }
                        else if (tdx.Format == Tdx.D3DFormat.DXT3)
                        {
                            flags |= Native.Flags.DXT3;
                        }
                        else if (tdx.Format == Tdx.D3DFormat.DXT5)
                        {
                            flags |= Native.Flags.DXT5;
                        }

                        var decompressed = Native.DecompressImage(
                            tdx.Mipmaps[0].Data,
                            tdx.Mipmaps[0].Width,
                            tdx.Mipmaps[0].Height,
                            flags);

                        var bitmap = MakeBitmapFromDXT(
                            tdx.Mipmaps[0].Width,
                            tdx.Mipmaps[0].Height,
                            decompressed,
                            true);

                        bitmap.Save(
                            Path.ChangeExtension(inputPath, ".png"),
                            ImageFormat.Png);
                    }
                    else if (tdx.Format == Tdx.D3DFormat.A8R8G8B8)
                    {
                        var bitmap = MakeBitmapFromA8R8G8B8(
                            tdx.Mipmaps[0].Width,
                            tdx.Mipmaps[0].Height,
                            tdx.Mipmaps[0].Data);

                        bitmap.Save(
                            Path.ChangeExtension(inputPath, ".png"),
                            ImageFormat.Png);
                    }
                    else if (tdx.Format == Tdx.D3DFormat.A4R4G4B4)
                    {
                        var bitmap = MakeBitmapFromA4R4G4B4(
                            tdx.Mipmaps[0].Width,
                            tdx.Mipmaps[0].Height,
                            tdx.Mipmaps[0].Data);

                        bitmap.Save(
                            Path.ChangeExtension(inputPath, ".png"),
                            ImageFormat.Png);
                    }
                    else if (tdx.Format == Tdx.D3DFormat.X8R8G8B8)
                    {
                        var bitmap = MakeBitmapFromX8R8G8B8(
                            tdx.Mipmaps[0].Width,
                            tdx.Mipmaps[0].Height,
                            tdx.Mipmaps[0].Data);

                        bitmap.Save(
                            Path.ChangeExtension(inputPath, ".png"),
                            ImageFormat.Png);
                    }
                    else
                    {
                        throw new NotSupportedException("unsupported format " + tdx.Format.ToString());
                    }
                }
                // convert to tdx
                else
                {
                    // just a crappy convert to A8R8G8B8 for now...

                    using (var bitmap = new Bitmap(inputPath))
                    {
                        var tdx = new TdxFile();
                        tdx.Width  = (ushort)bitmap.Width;
                        tdx.Height = (ushort)bitmap.Height;
                        tdx.Flags  = 0;
                        tdx.Format = Tdx.D3DFormat.A8R8G8B8;

                        var mip = new Tdx.Mipmap();
                        mip.Width  = tdx.Width;
                        mip.Height = tdx.Height;

                        int stride = mip.Width * 4;

                        var area   = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
                        var buffer = new byte[mip.Height * stride];

                        var    bitmapData = bitmap.LockBits(area, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                        IntPtr scan       = bitmapData.Scan0;
                        for (int y = 0, o = 0; y < mip.Height; y++, o += stride)
                        {
                            Marshal.Copy(scan, buffer, o, stride);
                            scan += bitmapData.Stride;
                        }
                        bitmap.UnlockBits(bitmapData);

                        mip.Data = buffer;

                        tdx.Mipmaps.Add(mip);

                        using (var output = File.Create(Path.ChangeExtension(inputPath, ".TDX")))
                        {
                            tdx.Serialize(output);
                        }
                    }
                }
            }
        }