public static VmgInfo Create(Stream stream) { Span <byte> buffer = stackalloc byte[32]; var id = buffer.Slice(0, 12); stream.Read(id); if (!id.SequenceEqual(Magic)) { ThrowHelper.ThrowInvalidDataException("File doesn't start with VMG IFO magic."); } using var reader = new BigEndianBinaryReader(stream, Encoding.UTF8, true); stream.Seek(Constants.VersionNumberOffset, SeekOrigin.Begin); var versionSpan = buffer.Slice(0, 2); stream.Read(versionSpan); // 0x20 var info = new VmgInfo(); if (!IfoHelper.TryParseVersion(versionSpan, out var version)) { ThrowHelper.ThrowInvalidDataException("First byte of the version number should be 0."); } info.Version = version; info.Category = reader.ReadUInt32(); // 0x22 info.NumberOfVolumes = reader.ReadUInt16(); // 0x26 info.VolumeNumber = reader.ReadUInt16(); // 0x28 info.SideId = reader.ReadByte(); // 0x2a stream.Seek(Constants.NumberOfTitleSetsOffset, SeekOrigin.Begin); info.NumberOfTitleSets = reader.ReadUInt16(); // 0x3e int bytesRead = stream.Read(buffer); // 0x40 Debug.Assert( bytesRead == Constants.ProviderIdLength, $"Expected {nameof(bytesRead)} to be {Constants.ProviderIdLength}, got {bytesRead}"); info.ProviderId = Encoding.ASCII.GetString(buffer); info.VmgPos = reader.ReadUInt64(); // 0x60 stream.Seek(Constants.TableOfTitlesPointerOffset, SeekOrigin.Begin); stream.Seek(reader.ReadUInt32() * Constants.DvdSectorSize, SeekOrigin.Begin); info.TableOfTitles = ReadTableOfTitles(reader); stream.Seek(Constants.VideoAttributesOffset, SeekOrigin.Begin); info.VideoAttributes = new VideoAttributes(reader.ReadUInt16()); // 0x100 info.AudioStreams = reader.ReadUInt16(); // 0x102 info.AudioAttributes = new AudioAttributes(reader.ReadUInt64()); // 0x104 return(info); }
public static VmgInfo GetVmgInfo(string rootDir) { var videoTsDir = rootDir; foreach (var dir in Directory.EnumerateDirectories(rootDir)) { if (dir.Equals("VIDEO_TS", StringComparison.OrdinalIgnoreCase)) { videoTsDir = dir; } } var files = Directory.GetFiles(videoTsDir); var vmgFile = Array.Find(files, x => x.Equals("VIDEO_TS.IFO", StringComparison.OrdinalIgnoreCase)) ?? Array.Find(files, x => x.Equals("VIDEO_TS.BUP", StringComparison.OrdinalIgnoreCase)); if (vmgFile == null) { ThrowHelper.ThrowFileNotFoundException("Couldn't find a 'VIDEO_TS.IFO' or 'VIDEO_TS.BUP' file."); } return(VmgInfo.Create(vmgFile)); }