示例#1
0
        public static ImcFile FromFile(string fileName)
        {
            var imc = new ImcFile();

            imc.FileName = fileName;

            FileStream filestream = null;

            try
            {
                filestream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

                using (BinaryReader file = new BinaryReader(filestream))
                {
                    filestream = null;

                    if (Encoding.ASCII.GetString(file.ReadBytes(4)) != "MCMP")
                    {
                        throw new InvalidDataException();
                    }

                    int entriesCount = file.ReadBigEndianInt16();

                    file.BaseStream.Seek(9, SeekOrigin.Current);

                    for (int i = 0; i < entriesCount - 1; i++)
                    {
                        var entry = new ImcEntry();

                        entry.Codec          = file.ReadByte();
                        entry.RawSize        = file.ReadBigEndianInt32();
                        entry.CompressedSize = file.ReadBigEndianInt32();

                        imc.Entries.Add(entry);
                    }

                    int codecsCount = file.ReadBigEndianInt16() / 5;

                    for (int i = 0; i < codecsCount; i++)
                    {
                        imc.Codecs.Add(Encoding.ASCII.GetString(file.ReadBytes(4)));
                        file.ReadByte();
                    }

                    if (imc.Codecs.Count != 2 ||
                        !string.Equals(imc.Codecs[0], "NULL", StringComparison.Ordinal) ||
                        !string.Equals(imc.Codecs[1], "VIMA", StringComparison.Ordinal))
                    {
                        throw new NotSupportedException();
                    }

                    if (Encoding.ASCII.GetString(file.ReadBytes(4)) != "iMUS")
                    {
                        throw new InvalidDataException();
                    }

                    int imusRawSize = file.ReadInt32();

                    if (Encoding.ASCII.GetString(file.ReadBytes(4)) != "MAP ")
                    {
                        throw new InvalidDataException();
                    }

                    ImcFile.ReadMap(imc, file, imusRawSize);

                    if (Encoding.ASCII.GetString(file.ReadBytes(4)) != "DATA")
                    {
                        throw new InvalidDataException();
                    }

                    imc.DataRawSize = file.ReadBigEndianInt32();

                    if (imc.DataRawSize != imc.Entries.Sum(t => t.RawSize))
                    {
                        throw new InvalidDataException();
                    }

                    foreach (var entry in imc.Entries)
                    {
                        entry.Data = file.ReadBytes(entry.CompressedSize);
                    }

                    if (file.BaseStream.Position != file.BaseStream.Length)
                    {
                        throw new InvalidDataException("End of file not reached.");
                    }

                    imc.ComputeEntriesOffsets();
                }
            }
            finally
            {
                if (filestream != null)
                {
                    filestream.Dispose();
                }
            }

            return(imc);
        }