Exemplo n.º 1
0
        private static void ConvertTexture(Stream input, TextureDX10ArchiveFile.Entry entry, Stream output)
        {
            const Endian endian = Endian.Little;

            var header = new Squish.DDS.Header();

            header.Size              = header.GetSize();
            header.Flags             = Squish.DDS.HeaderFlags.Texture | Squish.DDS.HeaderFlags.Mipmap;
            header.Width             = entry.Width;
            header.Height            = entry.Height;
            header.PitchOrLinearSize = 0;
            header.Depth             = 0;
            header.MipMapCount       = entry.MipMapCount;
            header.PixelFormat       = GetPixelFormat(entry);
            header.SurfaceFlags      = 8;
            header.CubemapFlags      = 0;

            output.WriteValueU32(0x20534444, endian);
            header.Serialize(output, endian);

            if (header.PixelFormat.FourCC == 0x30315844)
            {
                output.WriteValueU32(entry.Format, endian);
                output.WriteValueU32(2, endian);
                output.WriteValueU32(0, endian);
                output.WriteValueU32(1, endian);
                output.WriteValueU32(0, endian);
            }

            foreach (var mipMap in entry.MipMaps)
            {
                if (mipMap.DataCompressedSize == 0)
                {
                    input.Seek(mipMap.DataOffset, SeekOrigin.Begin);
                    output.WriteFromStream(input, mipMap.DataUncompressedSize);
                }
                else
                {
                    input.Seek(mipMap.DataOffset, SeekOrigin.Begin);
                    var zlib = new InflaterInputStream(input);
                    output.WriteFromStream(zlib, mipMap.DataUncompressedSize);
                }
            }
        }
        private static bool SaveDDSFile(string outputBaseName, uint elementIndex, TextureFile texture, Stream ddscFile)
        {
            string hmddscFile = outputBaseName + ".hmddsc";
            string fileName   = outputBaseName + elementIndex.ToString() + ".dds";
            bool   doClose    = false;

            if (ddscFile == null)
            {
                doClose = true;
                if (!File.Exists(hmddscFile))
                {
                    return(false);
                }
                ddscFile = File.OpenRead(hmddscFile);
            }

            int rank = 0;

            for (uint i = 0; i < texture.Elements.Length; ++i)
            {
                if (i == elementIndex)
                {
                    continue;
                }
                if (texture.Elements[i].Size > texture.Elements[elementIndex].Size)
                {
                    ++rank;
                }
            }

            // create the DDS the header
            var header = new Squish.DDS.Header()
            {
                Size              = 124,
                Flags             = Squish.DDS.HeaderFlags.Texture | Squish.DDS.HeaderFlags.Mipmap,
                Width             = texture.Width >> rank,
                Height            = texture.Height >> rank,
                PitchOrLinearSize = 0,
                Depth             = texture.Depth,
                MipMapCount       = 1, // always 1
                PixelFormat       = GetPixelFormat(texture),
                SurfaceFlags      = 8 | 0x1000,
                CubemapFlags      = 0,
            };

            using (var output = File.Create(fileName))
            {
                // write the DDS header
                var endian = Endian.Little;
                output.WriteValueU32(0x20534444, endian);
                header.Serialize(output, endian);

                // DX10 header
                if (header.PixelFormat.FourCC == 0x30315844)
                {
                    output.WriteValueU32(texture.Format, endian);
                    output.WriteValueU32(3, endian); // was 2. should be 3 as we most likely will export 2D textures
                    output.WriteValueU32(0, endian);
                    output.WriteValueU32(1, endian);
                    output.WriteValueU32(0, endian);
                }

                // body
                ddscFile.Position = texture.Elements[elementIndex].Offset;
                output.WriteFromStream(ddscFile, texture.Elements[elementIndex].Size);
            }
            if (doClose)
            {
                ddscFile.Close();
            }
            return(true);
        }
Exemplo n.º 3
0
        private static void Main(string[] args)
        {
            bool showHelp       = false;
            bool overwriteFiles = false;
            bool verbose        = true;

            var options = new OptionSet()
            {
                { "o|overwrite", "overwrite existing files", v => overwriteFiles = v != null },
                { "v|verbose", "be verbose", v => verbose = v != null },
                { "h|help", "show this message and exit", v => showHelp = v != null },
            };

            List <string> extras;

            try
            {
                extras = 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 (extras.Count < 1 ||
                extras.Count > 2 ||
                showHelp == true)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ input_file.ddsc [output_file.dds]", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            string inputPath  = extras[0];
            string outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, null) + ".dds";

            using (var input = File.OpenRead(inputPath))
            {
                var texture = new TextureFile();
                texture.Deserialize(input);

                using (var output = File.Create(outputPath))
                {
                    const Endian endian = Endian.Little;

                    var header = new Squish.DDS.Header()
                    {
                        Flags             = Squish.DDS.HeaderFlags.Texture | Squish.DDS.HeaderFlags.Mipmap,
                        Width             = texture.Width,
                        Height            = texture.Height,
                        PitchOrLinearSize = 0,
                        Depth             = 0,
                        MipMapCount       = texture.MipCount,
                        PixelFormat       = GetPixelFormat(texture),
                        SurfaceFlags      = 8,
                        CubemapFlags      = 0,
                    };

                    output.WriteValueU32(0x20534444, endian);
                    header.Serialize(output, endian);

                    if (header.PixelFormat.FourCC == 0x30315844)
                    {
                        output.WriteValueU32(texture.Format, endian);
                        output.WriteValueU32(2, endian);
                        output.WriteValueU32(0, endian);
                        output.WriteValueU32(1, endian);
                        output.WriteValueU32(0, endian);
                    }

                    input.Position = texture.Elements[0].Offset;
                    output.WriteFromStream(input, texture.Elements[0].Size);
                }
            }
        }
        private static bool ReadDDSFile(string ddsFile, int elementIndex, TextureFile texture, byte[][] contents, bool haveHMDDSCFile)
        {
            int rank = 0;

            for (uint i = 0; i < texture.Elements.Length; ++i)
            {
                if (i == elementIndex)
                {
                    continue;
                }
                if (texture.Elements[i].Size > texture.Elements[elementIndex].Size)
                {
                    ++rank;
                }
            }

            byte[] ddsContents;
            using (var ddsInput = File.OpenRead(ddsFile))
            {
                uint magic = ddsInput.ReadValueU32();
                if (magic != 0x20534444)
                {
                    throw new NotSupportedException(ddsFile + " is not a valid DDS file [magic does not match]");
                }

                // load the DDS header
                var header = new Squish.DDS.Header();
                header.Deserialize(ddsInput, Endian.Little);

                // if any, load the DX10 header
                if (header.PixelFormat.FourCC == 0x30315844)
                {
                    uint format = ddsInput.ReadValueU32();
                    if (ddsInput.ReadValueU32() != 3)
                    {
                        throw new NotImplementedException("1D/3D texture not implementeds");
                    }
                    if (ddsInput.ReadValueU32() != 0)
                    {
                        throw new NotImplementedException();
                    }
                    if (ddsInput.ReadValueU32() != 1)
                    {
                        throw new NotImplementedException();
                    }
                    if (ddsInput.ReadValueU32() != 0)
                    {
                        throw new NotImplementedException();
                    }

                    if (format != texture.Format)
                    {
                        Console.WriteLine("FORMAT IS DIFFERENT FROM THE ORIGINAL FILE");
                        return(false);
                    }
                    texture.Format = format;
                }

                // some checks
                if (header.Height << rank != texture.Height || header.Width << rank != texture.Width)
                {
                    Console.WriteLine("DIMENSIONS ARE DIFFERENTS FROM THE ORIGINAL FILE");
                    return(false);
                }

                // load the content of the texture
                ddsContents = ddsInput.ReadBytes((int)(ddsInput.Length - ddsInput.Position));

                if (!haveHMDDSCFile) // the easy way
                {
                    contents[elementIndex] = ddsContents;
                }
                else // load the contents byte by byte
                {
                    // the list of elements, sorted by rank (biggest first)
                    List <int> rankIndexes = new List <int>();
                    for (int i = 0; i < texture.Elements.Length; ++i)
                    {
                        int insertIndex = 0;
                        for (; insertIndex < rankIndexes.Count; ++insertIndex)
                        {
                            if (texture.Elements[rankIndexes[insertIndex]].Size < texture.Elements[i].Size)
                            {
                                break;
                            }
                        }
                        rankIndexes.Insert(insertIndex, i);
                    }
                    // the for all those indexes, insert ranges of the dds file
                    uint currentOffset = 0;
                    foreach (int index in rankIndexes)
                    {
                        uint sz = texture.Elements[index].Size;
                        contents[index] = new byte[sz];
                        for (int i = 0; i < sz; ++i)
                        {
                            contents[index][i] = ddsContents[currentOffset + i];
                        }
                        currentOffset += sz;
                    }
                }

                if ((uint)(texture.Elements[elementIndex].Size / 50) != (uint)(ddsContents.Length / 50) && !haveHMDDSCFile)
                {
                    Console.WriteLine("SIZE IS DIFFERENT FROM THE ORIGINAL FILE ({0} vs {1})",
                                      ddsContents.Length, texture.Elements[elementIndex].Size);
                    return(false);
                }
            }

            return(true);
        }