예제 #1
0
        // Methods
        public override void Read(ExtendedBinaryReader reader)
        {
            // PACx Header
            string sig = reader.ReadSignature(4);

            if (sig != PACxSignature)
            {
                throw new InvalidSignatureException(PACxSignature, sig);
            }

            // Version String
            string verString = reader.ReadSignature(3);

            if (!ushort.TryParse(verString, out Version))
            {
                throw new InvalidSignatureException(PACxSignature + Version, sig + verString);
            }

            reader.IsBigEndian = IsBigEndian =
                (reader.ReadChar() == BigEndianFlag);

            ID       = reader.ReadUInt32();
            FileSize = reader.ReadUInt32();

            RootOffset           = reader.ReadUInt32();
            RootCompressedLength = reader.ReadUInt32();
            RootLength           = reader.ReadUInt32();

            var flags = reader.ReadInt16();

            HasDependencies     = (flags & 0x2) != 0;
            HasCompressedBlocks = (flags & 0x1) != 0;

            ushort uk1 = reader.ReadUInt16();

            if (!HasCompressedBlocks && uk1 != UnknownConstant)
            {
                Console.WriteLine($"WARNING: Unknown1 != 0x108! ({uk1})");
            }
            else if (HasCompressedBlocks && uk1 != UnknownConstant1)
            {
                Console.WriteLine($"WARNING: Unknown1 != 0x208! ({uk1})");
            }

            if ((flags & 0x80) != 0)
            {
                DependencyEntriesLength = reader.ReadUInt32();
                CompressedChunksLength  = reader.ReadUInt32();
                StringTableLength       = reader.ReadUInt32();
                FinalTableLength        = reader.ReadUInt32();

                Length = LengthWithFlags;
            }
            else
            {
                Length = LengthWithoutFlags;
            }

            reader.Offset = Length;
        }
예제 #2
0
 public void Load(ExtendedBinaryReader reader)
 {
     TextureFullPath = reader.ReadSignature(0x200).Trim('\0');
     TextureFileName = reader.ReadSignature(0x080).Trim('\0');
     TextureWidth    = reader.ReadInt32();
     TextureHeight   = reader.ReadInt32();
     reader.JumpAhead(0x84); // Unknown
 }
예제 #3
0
        // Methods
        public override void Read(ExtendedBinaryReader reader)
        {
            // BINA Header
            string sig = reader.ReadSignature(4);

            if (sig != Signature)
            {
                throw new InvalidSignatureException(Signature, sig);
            }

            // Version String
            string verString = reader.ReadSignature(3);

            if (!ushort.TryParse(verString, out Version))
            {
                Console.WriteLine(
                    "WARNING: BINA header version was invalid! ({0})",
                    verString);
            }

            reader.IsBigEndian = IsBigEndian =
                (reader.ReadChar() == BigEndianFlag);
            FileSize = reader.ReadUInt32();

            ushort nodeCount = reader.ReadUInt16();
            ushort unknown1  = reader.ReadUInt16(); // Always 0? Padding??

            // TODO: Read Nodes Properly
            if (nodeCount < 1)
            {
                return;
            }

            // DATA Header
            string dataSig = reader.ReadSignature();

            if (dataSig != DataSignature)
            {
                throw new InvalidSignatureException(DataSignature, dataSig);
            }

            DataLength        = reader.ReadUInt32();
            StringTableOffset = reader.ReadUInt32();
            StringTableLength = reader.ReadUInt32();
            FinalTableLength  = reader.ReadUInt32();

            // Additional data
            ushort additionalDataLength = reader.ReadUInt16();
            ushort unknown3             = reader.ReadUInt16(); // Padding?

            reader.JumpAhead(additionalDataLength);
            reader.Offset = (uint)reader.BaseStream.Position;
        }
예제 #4
0
        public override void Load(ExtendedBinaryReader reader, bool keepOpen = false)
        {
            // Check if file has a signature
            string sig = reader.ReadSignature();

            if (sig == "STSC")
            { // Newer script format
                uint headerSize = reader.ReadUInt32();
                Version = reader.ReadUInt32();
                switch (Version)
                {
                case 4:     // Date A Live: Twin Edition Rio Reincarnation (PSV)
                    ScriptID = reader.ReadUInt16();
                    break;

                case 7:     // Date A Live: Rio Reincarnation (PC)
                    ScriptName = reader.ReadNullTerminatedString();
                    reader.JumpAhead((uint)(0x20 - (ScriptName.Length + 1)));
                    reader.JumpAhead(12);
                    ScriptID = reader.ReadUInt32();
                    break;
                }
            }
            else
            { // Older script format
                // Jump back as older scripts have much smaller headers
                reader.JumpBehind(4);
                ScriptID = reader.ReadUInt16();
            }
            // Stupid workaround to find the end of the code segment
            reader.Offset = (uint)reader.BaseStream.Length;
            while (true)
            {
                byte opcode = reader.ReadByte();

                if (opcode >= 0x94)
                {
                    throw new STSCDisassembleException(this,
                                                       $"Got opcode 0x{opcode:X2} at 0x{reader.BaseStream.Position - 1:X8} in \"{ScriptName}\"" +
                                                       " There is no opcodes larger than 0x93!");
                }

                // Check if its a known instruction
                if (STSCInstructions.DALRRInstructions[opcode] == null)
                {
                    throw new STSCDisassembleException(this,
                                                       $"Got opcode 0x{opcode:X2} at 0x{reader.BaseStream.Position - 1:X8} in \"{ScriptName}\"" +
                                                       " This opcode is unknown!");
                }

                var instruction = STSCInstructions.DALRRInstructions[opcode].Read(reader);
                Instructions.Add(instruction);
                if (reader.BaseStream.Position >= reader.Offset)
                {
                    break;
                }
            }
        }
예제 #5
0
        // Methods
        public override void Load(Stream fileStream)
        {
            // Header
            var    reader = new ExtendedBinaryReader(fileStream, Encoding.ASCII, false);
            string sig    = reader.ReadSignature();

            if (sig != Signature)
            {
                throw new InvalidSignatureException(Signature, sig);
            }

            // Textures
            uint totalFrameCount = reader.ReadUInt32();
            byte textureCount    = reader.ReadByte();

            for (int i = 0; i < textureCount; ++i)
            {
                Textures.Add(new Texture()
                {
                    FilePath = reader.ReadString(),
                    Unknown1 = reader.ReadByte()
                });
            }

            // Animations
            ushort animCount = reader.ReadUInt16();

            for (int i2 = 0; i2 < animCount; ++i2)
            {
                var anim = new Animation()
                {
                    Name = reader.ReadString()
                };

                ushort frameCount = reader.ReadUInt16();
                anim.Unknown1 = reader.ReadInt16();
                anim.Unknown2 = reader.ReadInt16();

                // Animation Frames
                for (int i3 = 0; i3 < frameCount; ++i3)
                {
                    anim.Frames.Add(new Frame()
                    {
                        TextureIndex = reader.ReadByte(),
                        Unknown1     = reader.ReadInt16(),
                        Unknown2     = reader.ReadInt16(),
                        X            = reader.ReadUInt16(),
                        Y            = reader.ReadUInt16(),
                        Width        = reader.ReadUInt16(),
                        Height       = reader.ReadUInt16(),
                        OriginX      = reader.ReadInt16(),
                        OriginY      = reader.ReadInt16()
                    });
                }

                Animations.Add(anim);
            }
        }
예제 #6
0
        // Methods
        public override void Read(ExtendedBinaryReader reader)
        {
            // PACx Header
            string sig = reader.ReadSignature(4);

            if (sig != PACxSignature)
            {
                throw new InvalidSignatureException(PACxSignature, sig);
            }

            // Version String
            string verString = reader.ReadSignature(3);

            if (!ushort.TryParse(verString, out Version))
            {
                Console.WriteLine(
                    "WARNING: PACx header version was invalid! ({0})",
                    verString);
            }

            reader.IsBigEndian = IsBigEndian =
                (reader.ReadChar() == BigEndianFlag);

            ID       = reader.ReadUInt32();
            FileSize = reader.ReadUInt32();

            NodeTreeLength    = reader.ReadUInt32();
            SplitListLength   = reader.ReadUInt32();
            FileEntriesLength = reader.ReadUInt32();
            StringTableLength = reader.ReadUInt32();

            DataLength       = reader.ReadUInt32();
            FinalTableLength = reader.ReadUInt32();
            PacType          = (PACTypes)reader.ReadUInt16();

            ushort uk1 = reader.ReadUInt16();

            if (uk1 != UnknownConstant)
            {
                Console.WriteLine($"WARNING: Unknown1 != 0x108! ({uk1})");
            }

            SplitCount    = reader.ReadUInt32();
            reader.Offset = Length;
        }
예제 #7
0
        // TODO
        protected void LoadShadowArchive(ExtendedBinaryReader reader)
        {
            reader.JumpAhead(0x4);                                 // Unknown, Seems to always be 0
            uint   fileSize   = reader.ReadUInt32();               // File Size - 0xC
            uint   magic      = reader.ReadUInt32();               // Magic
            string ONEVersion = reader.ReadNullTerminatedString(); // Gets the version String

            reader.FixPadding();                                   // Aligns the reader

            uint fileCount = reader.ReadUInt32();                  // File Count

            reader.JumpAhead(0x38 * 2 + 0x20);                     // Jump to the third/first entry
            bool isVersion6     = ONEVersion == "ONE Ver 0.60";    // Checks if its version is 0.60
            int  fileNameLength = isVersion6 ? 0x2C : 0x20;        // The max file name size

            // Read File List
            var files = new FileEntry[FileEntryCount];

            for (int i = 0; i < fileCount; i++)
            {
                var entry = new FileEntry();
                entry.FileName = reader.ReadSignature(
                    fileNameLength).Replace("\0", string.Empty);

                entry.UncompressedSize = reader.ReadUInt32();
                entry.DataOffset       = reader.ReadUInt32();
                reader.JumpAhead(4); // Unknown, Seems to always be 1

                if (!isVersion6)
                {
                    reader.JumpAhead(0xC); // Unknown, Seems to always be 0
                }
                files[i] = entry;
            }

            // Read File Data
            if (files.Length > 0)
            {
                reader.JumpTo(files[0].DataOffset + 0xC);
                for (int i = 0; i < fileCount; ++i)
                {
                    // Compute the file's data length
                    files[i].DataLength = ((i == fileCount - 1) ?
                                           fileSize + 0xC : files[i + 1].DataOffset) - files[i].DataOffset;

                    var file = new ArchiveFile()
                    {
                        Name = files[i].FileName,
                        Data = reader.ReadBytes(
                            (int)files[i].DataLength) // TODO: Decompress file
                    };
                    Data.Add(file);
                }
            }
        }
예제 #8
0
        public override void Load(Stream fileStream)
        {
            var reader = new ExtendedBinaryReader(fileStream, false);

            reader.JumpAhead(4); // CRC32?
            int fileCount = reader.ReadInt32();

            var fileEntries = new List <FileEntry>();

            for (int i = 0; i < fileCount; ++i)
            {
                var fileEntry = new FileEntry();
                fileEntry.FileName             = reader.ReadSignature(0x40).Replace("\0", "");
                fileEntry.DataUncompressedSize = reader.ReadUInt32();
                fileEntry.DataSize             = reader.ReadUInt32();
                fileEntry.DataOffset           = reader.ReadUInt32();
                fileEntry.Compressed           = reader.ReadByte() == 1;
                reader.JumpAhead(3); // Other Attributes?
                fileEntries.Add(fileEntry);
            }

            foreach (var fileEntry in fileEntries)
            {
                reader.JumpTo(fileEntry.DataOffset);

                byte[] data = null;
                if (fileEntry.Compressed)
                {
                    data = ReadAndDecompress(reader);
                }
                else
                {
                    data = reader.ReadBytes((int)fileEntry.DataUncompressedSize);
                }

                // Adds the File
                Data.Add(new ArchiveFile()
                {
                    Name = fileEntry.FileName,
                    Data = data
                });
            }
        }
예제 #9
0
            public override void Load(Stream fileStream)
            {
                var    reader = new ExtendedBinaryReader(fileStream, true);
                string sig    = reader.ReadSignature();

                if (sig != "SCSE")
                {
                    throw new InvalidSignatureException("SCSE", sig);
                }
                int entryCount = reader.ReadInt32();

                for (int i = 0; i < entryCount; ++i)
                {
                    var entry = new Entry();
                    entry.OrcFileName  = reader.ReadString();
                    entry.FriendlyName = reader.ReadString();
                    Entries.Add(entry);
                }
            }
        public static void LoadConfig(Stream stream)
        {
            var    reader = new ExtendedBinaryReader(stream, true);
            string sig    = reader.ReadSignature();

            if (sig != "SCSE")
            {
                throw new InvalidSignatureException("SCSE", sig);
            }

            if (reader.ReadUInt16() != ConfigVersion)
            { // Old Config
                stream.Close();
                File.Delete(((FileStream)stream).Name);
                return;
            }

            DolphinExecutablePath = ReadEntry(reader);
            GameRootPath          = ReadEntry(reader);
        }
예제 #11
0
            public void Load(ExtendedBinaryReader reader)
            {
                LayerName = reader.ReadSignature(0x20);
                uint unknown20 = reader.ReadUInt32();

                TextureID = reader.ReadInt32();
                uint Offset    = reader.ReadUInt32();
                uint unknown2C = reader.ReadUInt32();

                //
                uint oldpos = (uint)reader.GetPosition();

                reader.JumpTo(Offset);

                reader.JumpAhead(0x164);
                LayerOffX = reader.ReadSingle();
                LayerOffY = reader.ReadSingle();
                reader.JumpAhead(4);
                LayerWidth  = reader.ReadSingle();
                LayerHeight = reader.ReadSingle();

                reader.JumpAhead(0x88); // Unknown

                /*
                 * Top Left
                 * Top Right
                 * Bottom Left
                 * Bottom Right
                 */

                for (int i = 0; i < 4; ++i)
                {
                    Verts.Add(new MAVert(reader));
                }

                reader.JumpTo(oldpos);

                reader.JumpAhead(0x84); // Unknown
            }
예제 #12
0
        // Methods
        public override void Read(ExtendedBinaryReader reader)
        {
            // We need to know whether the file is big or little endian first
            var pos = reader.BaseStream.Position;

            reader.BaseStream.Position += 0x14;
            reader.IsBigEndian          = false;

            // Version String/Endian Flag
            uint   binaFlags = reader.ReadUInt32();
            string verString = "xyz"; // Just 3 chars that would fail ushort.TryParse

            unsafe
            {
                // Endian Flag
                reader.IsBigEndian = IsBigEndian = ((char)(
                                                        (binaFlags & 0xFF000000) >> 24) == BigEndianFlag);

                // Quick way to grab the last 3 bytes from binaFlags (which
                // are chars) and stuff them into a string we can then
                // safely parse into a ushort via ushort.TryParse
                fixed(char *vp = verString)
                {
                    *vp = (char)((binaFlags & 0xFF0000) >> 16);
                    vp[1] = (char)((binaFlags & 0xFF00) >> 16);
                    vp[2] = (char)(binaFlags & 0xFF);
                }
            }

            if (!ushort.TryParse(verString, out Version))
            {
                Console.WriteLine(
                    "WARNING: BINA header version was invalid! ({0})",
                    verString);
            }

            // Alright, cool, *NOW* we can read the rest of the header
            reader.BaseStream.Position = pos;

            // Header
            FileSize         = reader.ReadUInt32();
            FinalTableOffset = reader.ReadUInt32();
            FinalTableLength = reader.ReadUInt32();

            uint unknown1 = reader.ReadUInt32();

            if (unknown1 != 0)
            {
                Console.WriteLine($"WARNING: Unknown1 is not zero! ({unknown1})");
            }

            ushort unknownFlag1 = reader.ReadUInt16();

            if (unknownFlag1 != 0)
            {
                Console.WriteLine($"WARNING: UnknownFlag1 is not zero! ({unknownFlag1})");
            }

            IsFooterMagicPresent = (reader.ReadUInt16() == 1); // FooterNodeCount?
            reader.JumpAhead(4);

            // BINA Signature
            string sig = reader.ReadSignature(4);

            if (sig != Signature)
            {
                throw new InvalidSignatureException(Signature, sig);
            }

            // TODO: Find out what this is. Maybe additional data length?
            uint unknown2 = reader.ReadUInt32();

            if (unknown2 != 0)
            {
                Console.WriteLine($"WARNING: Unknown2 is not zero! ({unknown2})");
            }

            reader.Offset = (uint)reader.BaseStream.Position;
        }
예제 #13
0
        // Methods
        public override void Load(Stream fileStream)
        {
            // Signature
            var reader = new ExtendedBinaryReader(
                fileStream, Encoding.ASCII, false);

            string sig = reader.ReadSignature(4);

            if (sig != Signature)
            {
                throw new InvalidSignatureException(Signature, sig);
            }

            // Header
            Header = new DDSHeader()
            {
                Size  = reader.ReadUInt32(),
                Flags = reader.ReadUInt32()
            };

            if (!Header.HasFlag(DDSHeader.FLAGS.CAPS) ||
                !Header.HasFlag(DDSHeader.FLAGS.WIDTH) ||
                !Header.HasFlag(DDSHeader.FLAGS.HEIGHT) ||
                !Header.HasFlag(DDSHeader.FLAGS.PIXEL_FORMAT))
            {
                throw new Exception(
                          "Could not load DDS file. Required header flags are missing!");
            }

            Height = reader.ReadUInt32();
            Width  = reader.ReadUInt32();

            Header.PitchOrLinearSize = reader.ReadUInt32();
            Header.Depth             = reader.ReadUInt32();
            Header.MipmapCount       = reader.ReadUInt32();

            reader.JumpAhead(44); // Skip past padding
            Header.PixelFormat = new DDSPixelFormat(reader);

            Header.Caps  = reader.ReadUInt32();
            Header.Caps2 = reader.ReadUInt32();
            Header.Caps3 = reader.ReadUInt32();
            Header.Caps4 = reader.ReadUInt32();

            reader.JumpTo(Header.Size + 4, true);

            // Depth
            uint depth = 1;

            if (Header.HasFlag(DDSHeader.FLAGS.DEPTH) &&
                Header.HasFlag(DDSHeader.CAPS2.VOLUME))
            {
                depth = Header.Depth;

                // TODO
                throw new NotImplementedException(
                          "Reading 3D textures from DDS files is not yet supported.");
            }
            else if (Header.HasFlag(DDSHeader.CAPS2.CUBEMAP))
            {
                depth = 6;

                // TODO
                throw new NotImplementedException(
                          "Reading DDS cubemaps is not yet supported.");
            }

            // MipMaps
            uint mipmapCount = 1;

            if (Header.HasFlag(DDSHeader.FLAGS.MIPMAP_COUNT) &&
                Header.HasFlag(DDSHeader.CAPS.MIPMAP))
            {
                mipmapCount = Header.MipmapCount;
            }

            MipmapCount = mipmapCount;

            // Caps
            if (!Header.HasFlag(DDSHeader.CAPS.TEXTURE))
            {
                throw new Exception(
                          "Could not load DDS file. Required CAPS flag is missing!");
            }
            // TODO

            // Caps2
            // TODO

            // DX10 Header/Pixel Format
            uint pixelsPerBlock = 16;
            byte blockSize;

            if (Header.PixelFormat.HasFlag(DDSPixelFormat.FLAGS.FOURCC))
            {
                switch ((DDSPixelFormat.FOURCCS)Header.PixelFormat.FourCC)
                {
                // DX10 Header
                case DDSPixelFormat.FOURCCS.DX10:
                {
                    var dx10Header = new DX10Header(reader);
                    depth = dx10Header.ArraySize;

                    switch ((DX10Header.DXGI_FORMATS)dx10Header.DXGIFormat)
                    {
                    // BC1
                    case DX10Header.DXGI_FORMATS.BC1_TYPELESS:
                    case DX10Header.DXGI_FORMATS.BC1_UNORM:
                        CompressionFormat = CompressionFormats.RGB_S3TC_DXT1_EXT;
                        blockSize         = 8;
                        break;

                    // BC3
                    case DX10Header.DXGI_FORMATS.BC3_TYPELESS:
                    case DX10Header.DXGI_FORMATS.BC3_UNORM:
                        CompressionFormat = CompressionFormats.RGBA_S3TC_DXT3_EXT;
                        blockSize         = 16;
                        break;

                    // BC5
                    case DX10Header.DXGI_FORMATS.BC5_TYPELESS:
                    case DX10Header.DXGI_FORMATS.BC5_SNORM:
                    case DX10Header.DXGI_FORMATS.BC5_UNORM:
                        CompressionFormat = CompressionFormats.RGBA_S3TC_DXT5_EXT;
                        blockSize         = 16;
                        break;

                    // BC7
                    case DX10Header.DXGI_FORMATS.BC7_TYPELESS:
                    case DX10Header.DXGI_FORMATS.BC7_UNORM:
                        CompressionFormat = CompressionFormats.RGBA_BPTC_UNORM_EXT;
                        blockSize         = 16;
                        break;

                    case DX10Header.DXGI_FORMATS.BC7_UNORM_SRGB:
                        CompressionFormat = CompressionFormats.SRGB_ALPHA_BPTC_UNORM_EXT;
                        blockSize         = 16;
                        break;

                    // TODO: Add support for BC1 SRGB, BC2, BC3 SRGB, BC4, and BC6
                    default:
                        throw new NotImplementedException(string.Format(
                                                              "Reading DX10 DXGI type \"{0}\" is not yet supported.",
                                                              dx10Header.DXGIFormat));
                    }

                    break;
                }

                // DXT1
                case DDSPixelFormat.FOURCCS.DXT1:
                    CompressionFormat = CompressionFormats.RGB_S3TC_DXT1_EXT;
                    blockSize         = 8;
                    break;

                // DXT3
                case DDSPixelFormat.FOURCCS.DXT3:
                    CompressionFormat = CompressionFormats.RGBA_S3TC_DXT3_EXT;
                    blockSize         = 16;
                    break;

                // DXT5
                case DDSPixelFormat.FOURCCS.DXT5:
                case DDSPixelFormat.FOURCCS.ATI2:
                case DDSPixelFormat.FOURCCS.BC5S:
                    CompressionFormat = CompressionFormats.RGBA_S3TC_DXT5_EXT;
                    blockSize         = 16;
                    break;

                // TODO: Add support for DXT2 and DXT4
                default:
                    throw new NotImplementedException(string.Format("{0} \"{1}\" {2}",
                                                                    "Reading DDS files with FOURCC",
                                                                    Header.PixelFormat.FourCC,
                                                                    "is not yet supported."));
                }
            }
            else
            {
                if (!Header.PixelFormat.HasFlag(DDSPixelFormat.FLAGS.RGB))
                {
                    throw new NotImplementedException(
                              "Reading DDS files without RGB data is not yet supported.");
                }

                if (Header.PixelFormat.RGBBitCount % 8 != 0)
                {
                    throw new InvalidDataException(
                              "RGBBitCount must be divisible by 8.");
                }

                if (Header.PixelFormat.RGBBitCount > 32)
                {
                    throw new InvalidDataException(
                              "RGBBitCount must be less than or equal to 32.");
                }

                if (Header.PixelFormat.RGBBitCount != 32)
                {
                    throw new NotImplementedException(
                              "Reading DDS files with non 32-bit data is not yet supported.");
                }

                pixelsPerBlock    = 1;
                CompressionFormat = CompressionFormats.None;
                blockSize         = (byte)(Header.PixelFormat.RGBBitCount / 8);
                PixelFormat       = PixelFormats.RGBA;
            }

            // Whether or not uncompressed pixels need to be re-arranged to RGBA
            bool isARGB = (CompressionFormat == CompressionFormats.None &&
                           Header.PixelFormat.RGBBitCount == 32 &&
                           Header.PixelFormat.ABitMask == 0xFF000000 &&
                           Header.PixelFormat.RBitMask == 0xFF0000 &&
                           Header.PixelFormat.GBitMask == 0xFF00 &&
                           Header.PixelFormat.BBitMask == 0xFF);

            // Data
            uint width = Width, height = Height;

            ColorData = new byte[mipmapCount * depth][];

            for (uint slice = 0; slice < depth; ++slice)
            {
                for (uint level = 0; level < mipmapCount; ++level)
                {
                    // Pad out width/height to 4x4 blocks
                    if (CompressionFormat != CompressionFormats.None)
                    {
                        if (width % 4 != 0)
                        {
                            width = ((width / 4) + 1) * 4;
                        }

                        if (height % 4 != 0)
                        {
                            height = ((height / 4) + 1) * 4;
                        }
                    }

                    // Compute size of this block
                    uint size = ((width * height) / pixelsPerBlock) * blockSize;

                    // Re-arrange uncompressed pixels to RGBA8 format if necessary
                    if (isARGB)
                    {
                        uint p;
                        ColorData[level] = new byte[size];

                        for (uint i = 0; i < size; i += 4)
                        {
                            // Convert from ARGB8 to RGBA8
                            p = reader.ReadUInt32();
                            ColorData[level][i]     = (byte)((p & Header.PixelFormat.RBitMask) >> 16);
                            ColorData[level][i + 1] =
                                (byte)((p & Header.PixelFormat.GBitMask) >> 8);

                            ColorData[level][i + 2] = (byte)(p & Header.PixelFormat.BBitMask);
                            ColorData[level][i + 3] =
                                (byte)((p & Header.PixelFormat.ABitMask) >> 24);
                        }
                    }

                    // Otherwise, simply read the block
                    else
                    {
                        ColorData[level] = reader.ReadBytes((int)size);
                    }

                    // Divide width/height by 2 for the next mipmap
                    width  /= 2;
                    height /= 2;
                }
            }
        }
예제 #14
0
        public static byte[] DecompressLZ77(this byte[] compressed)
        {
            byte[] buffer = null;
            using (var reader = new ExtendedBinaryReader(new MemoryStream(compressed)))
            {
                int  position     = 0;
                long flagPosition = 0;
                if (reader.ReadSignature() == "LZ77")
                {
                    int uncompressedSize = reader.ReadInt32();
                    int lz77Step         = reader.ReadInt32();
                    int offset           = reader.ReadInt32();
                    flagPosition = reader.GetPosition();
                    reader.JumpTo(offset);
                    buffer = new byte[uncompressedSize];
                }

                int flagCount = 0;
                int flag      = 0;
                while (true)
                {
                    if (flagCount == 0)
                    {
                        if (flagPosition >= compressed.Length)
                        {
                            break;
                        }
                        if (flagPosition == reader.GetPosition())
                        {
                            reader.JumpAhead(1);
                        }
                        flag      = compressed[flagPosition++];
                        flagCount = 8;
                    }
                    if ((flag & 0x80) != 0)
                    {
                        if (reader.GetPosition() + 2 > compressed.Length)
                        {
                            break;
                        }
                        int backStep = reader.ReadByte();
                        int amount   = reader.ReadByte();
                        for (amount += 3; (amount--) != 0; position++)
                        {
                            if (position >= buffer.Length)
                            {
                                break;
                            }
                            buffer[position] = buffer[position - backStep];
                        }
                    }
                    else
                    {
                        if (position >= buffer.Length)
                        {
                            break;
                        }
                        buffer[position++] = reader.ReadByte();
                    }
                    flag <<= 1;
                    flagCount--;
                }
            }
            return(buffer);
        }