diff --git a/DiscImageChef.Decoders/LisaTag.cs b/DiscImageChef.Decoders/LisaTag.cs index 2a56f015a..4c44e2278 100644 --- a/DiscImageChef.Decoders/LisaTag.cs +++ b/DiscImageChef.Decoders/LisaTag.cs @@ -88,6 +88,79 @@ namespace DiscImageChef.Decoders public bool IsFirst; /// On-memory value for easy last block search. public bool IsLast; + + /// + /// Converts this tag to Priam DataTower format + /// + public PriamTag ToPriam() + { + return new PriamTag + { + AbsPage = AbsPage, + Checksum = Checksum, + FileId = FileId, + IsFirst = IsFirst, + IsLast = IsLast, + Kind = Kind, + NextBlock = IsLast ? 0xFFFFFF : NextBlock & 0xFFFFFF, + PrevBlock = IsFirst ? 0xFFFFFF : PrevBlock & 0xFFFFFF, + RelPage = RelPage, + UsedBytes = UsedBytes, + ValidChk = ValidChk, + Version = Version, + Volume = Volume + }; + } + + /// + /// Converts this tag to Sony format + /// + public SonyTag Sony() + { + return new SonyTag + { + FileId = FileId, + IsFirst = IsFirst, + IsLast = IsLast, + Kind = Kind, + NextBlock = (ushort)NextBlock, + PrevBlock = (ushort)PrevBlock, + RelPage = RelPage, + Version = Version, + Volume = Volume + }; + } + + /// + /// Gets a byte array representation of this tag + /// + public byte[] GetBytes() + { + byte[] tagBytes = new byte[20]; + + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; + + byte[] tmp = BigEndianBitConverter.GetBytes(Version); + Array.Copy(tmp, 0, tagBytes, 0, 2); + tagBytes[2] = (byte)(Kind << 6); + tagBytes[3] = Volume; + tmp = BigEndianBitConverter.GetBytes(FileId); + Array.Copy(tmp, 0, tagBytes, 4, 2); + tmp = BigEndianBitConverter.GetBytes((ushort)(UsedBytes & 0x7FFF)); + Array.Copy(tmp, 0, tagBytes, 6, 2); + if(ValidChk) tagBytes[6] += 0x80; + tmp = BigEndianBitConverter.GetBytes(AbsPage); + Array.Copy(tmp, 1, tagBytes, 8, 3); + tagBytes[11] = Checksum; + tmp = BigEndianBitConverter.GetBytes(RelPage); + Array.Copy(tmp, 0, tagBytes, 12, 2); + tmp = BigEndianBitConverter.GetBytes(IsLast ? 0xFFFFFF : NextBlock); + Array.Copy(tmp, 1, tagBytes, 14, 3); + tmp = BigEndianBitConverter.GetBytes(IsFirst ? 0xFFFFFF : PrevBlock); + Array.Copy(tmp, 1, tagBytes, 17, 3); + + return tagBytes; + } } /// @@ -142,6 +215,81 @@ namespace DiscImageChef.Decoders public bool IsFirst; /// On-memory value for easy last block search. public bool IsLast; + + /// + /// Converts this tag to Apple Profile format + /// + public ProfileTag Profile() + { + return new ProfileTag + { + AbsPage = AbsPage, + Checksum = Checksum, + FileId = FileId, + IsFirst = IsFirst, + IsLast = IsLast, + Kind = Kind, + NextBlock = IsLast ? 0xFFFFFF : NextBlock & 0xFFFFFF, + PrevBlock = IsFirst ? 0xFFFFFF : PrevBlock & 0xFFFFFF, + RelPage = RelPage, + UsedBytes = UsedBytes, + ValidChk = ValidChk, + Version = Version, + Volume = Volume + }; + } + + /// + /// Converts this tag to Sony format + /// + public SonyTag ToSony() + { + return new SonyTag + { + FileId = FileId, + IsFirst = IsFirst, + IsLast = IsLast, + Kind = Kind, + NextBlock = (ushort)(IsLast ? 0x7FF : NextBlock & 0x7FF), + PrevBlock = (ushort)(IsFirst ? 0x7FF : PrevBlock & 0x7FF), + RelPage = RelPage, + Version = Version, + Volume = Volume + }; + } + + /// + /// Gets a byte array representation of this tag + /// + public byte[] GetBytes() + { + byte[] tagBytes = new byte[24]; + + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; + + byte[] tmp = BigEndianBitConverter.GetBytes(Version); + Array.Copy(tmp, 0, tagBytes, 0, 2); + tagBytes[2] = (byte)(Kind << 6); + tagBytes[3] = Volume; + tmp = BigEndianBitConverter.GetBytes(FileId); + Array.Copy(tmp, 0, tagBytes, 4, 2); + tmp = BigEndianBitConverter.GetBytes((ushort)(UsedBytes & 0x7FFF)); + Array.Copy(tmp, 0, tagBytes, 6, 2); + if(ValidChk) tagBytes[6] += 0x80; + tmp = BigEndianBitConverter.GetBytes(AbsPage); + Array.Copy(tmp, 1, tagBytes, 8, 3); + tagBytes[11] = Checksum; + tmp = BigEndianBitConverter.GetBytes(RelPage); + Array.Copy(tmp, 0, tagBytes, 12, 2); + tmp = BigEndianBitConverter.GetBytes(IsLast ? 0xFFFFFF : NextBlock); + Array.Copy(tmp, 1, tagBytes, 14, 3); + tmp = BigEndianBitConverter.GetBytes(IsFirst ? 0xFFFFFF : PrevBlock); + Array.Copy(tmp, 1, tagBytes, 17, 3); + tmp = BigEndianBitConverter.GetBytes(DiskSize); + Array.Copy(tmp, 0, tagBytes, 20, 4); + + return tagBytes; + } } /// @@ -176,6 +324,69 @@ namespace DiscImageChef.Decoders public bool IsFirst; /// On-memory value for easy last block search. public bool IsLast; + + /// + /// Converts this tag to Apple Profile format + /// + public ProfileTag ToProfile() + { + return new ProfileTag + { + FileId = FileId, + IsFirst = IsFirst, + IsLast = IsLast, + Kind = Kind, + NextBlock = (uint)(IsLast ? 0xFFFFFF : NextBlock & 0xFFFFFF), + PrevBlock = (uint)(IsFirst ? 0xFFFFFF : PrevBlock & 0xFFFFFF), + RelPage = RelPage, + Version = Version, + Volume = Volume + }; + } + + /// + /// Converts this tag to Priam DataTower format + /// + public PriamTag ToPriam() + { + return new PriamTag + { + FileId = FileId, + IsFirst = IsFirst, + IsLast = IsLast, + Kind = Kind, + NextBlock = (uint)(IsLast ? 0xFFFFFF : NextBlock & 0xFFFFFF), + PrevBlock = (uint)(IsFirst ? 0xFFFFFF : PrevBlock & 0xFFFFFF), + RelPage = RelPage, + Version = Version, + Volume = Volume + }; + } + + /// + /// Gets a byte array representation of this tag + /// + public byte[] GetBytes() + { + byte[] tagBytes = new byte[12]; + + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; + + byte[] tmp = BigEndianBitConverter.GetBytes(Version); + Array.Copy(tmp, 0, tagBytes, 0, 2); + tagBytes[2] = (byte)(Kind << 6); + tagBytes[3] = Volume; + tmp = BigEndianBitConverter.GetBytes(FileId); + Array.Copy(tmp, 0, tagBytes, 4, 2); + tmp = BigEndianBitConverter.GetBytes(RelPage); + Array.Copy(tmp, 0, tagBytes, 6, 2); + tmp = BigEndianBitConverter.GetBytes(IsLast ? 0x7FF : NextBlock); + Array.Copy(tmp, 1, tagBytes, 8, 2); + tmp = BigEndianBitConverter.GetBytes(IsFirst ? 0x7FF : PrevBlock); + Array.Copy(tmp, 1, tagBytes, 10, 2); + + return tagBytes; + } } public static SonyTag? DecodeSonyTag(byte[] tag) @@ -186,16 +397,16 @@ namespace DiscImageChef.Decoders BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; - snTag.Version = BigEndianBitConverter.ToUInt16(tag, 0); - snTag.Kind = (byte)((tag[2] & 0xC0) >> 6); - snTag.Reserved = (byte)(tag[2] & 0x3F); - snTag.Volume = tag[3]; - snTag.FileId = BigEndianBitConverter.ToInt16(tag, 4); - snTag.RelPage = BigEndianBitConverter.ToUInt16(tag, 6); - snTag.NextBlock = (ushort)(BigEndianBitConverter.ToUInt16(tag, 8) & 0x7FF); + snTag.Version = BigEndianBitConverter.ToUInt16(tag, 0); + snTag.Kind = (byte)((tag[2] & 0xC0) >> 6); + snTag.Reserved = (byte)(tag[2] & 0x3F); + snTag.Volume = tag[3]; + snTag.FileId = BigEndianBitConverter.ToInt16(tag, 4); + snTag.RelPage = BigEndianBitConverter.ToUInt16(tag, 6); + snTag.NextBlock = (ushort)(BigEndianBitConverter.ToUInt16(tag, 8) & 0x7FF); snTag.PrevBlock = (ushort)(BigEndianBitConverter.ToUInt16(tag, 10) & 0x7FF); - snTag.IsLast = snTag.NextBlock == 0x7FF; + snTag.IsLast = snTag.NextBlock == 0x7FF; snTag.IsFirst = snTag.PrevBlock == 0x7FF; return snTag; @@ -211,36 +422,36 @@ namespace DiscImageChef.Decoders byte[] tmp = new byte[4]; - phTag.Version = BigEndianBitConverter.ToUInt16(tag, 0); - phTag.Kind = (byte)((tag[2] & 0xC0) >> 6); - phTag.Reserved = (byte)(tag[2] & 0x3F); - phTag.Volume = tag[3]; - phTag.FileId = BigEndianBitConverter.ToInt16(tag, 4); - phTag.ValidChk |= (tag[6] & 0x80) == 0x80; - phTag.UsedBytes = (ushort)(BigEndianBitConverter.ToUInt16(tag, 6) & 0x7FFF); + phTag.Version = BigEndianBitConverter.ToUInt16(tag, 0); + phTag.Kind = (byte)((tag[2] & 0xC0) >> 6); + phTag.Reserved = (byte)(tag[2] & 0x3F); + phTag.Volume = tag[3]; + phTag.FileId = BigEndianBitConverter.ToInt16(tag, 4); + phTag.ValidChk |= (tag[6] & 0x80) == 0x80; + phTag.UsedBytes = (ushort)(BigEndianBitConverter.ToUInt16(tag, 6) & 0x7FFF); - tmp[0] = 0x00; - tmp[1] = tag[8]; - tmp[2] = tag[9]; - tmp[3] = tag[10]; + tmp[0] = 0x00; + tmp[1] = tag[8]; + tmp[2] = tag[9]; + tmp[3] = tag[10]; phTag.AbsPage = BigEndianBitConverter.ToUInt32(tmp, 0); phTag.Checksum = tag[11]; - phTag.RelPage = BigEndianBitConverter.ToUInt16(tag, 12); + phTag.RelPage = BigEndianBitConverter.ToUInt16(tag, 12); - tmp[0] = 0x00; - tmp[1] = tag[14]; - tmp[2] = tag[15]; - tmp[3] = tag[16]; + tmp[0] = 0x00; + tmp[1] = tag[14]; + tmp[2] = tag[15]; + tmp[3] = tag[16]; phTag.NextBlock = BigEndianBitConverter.ToUInt32(tmp, 0); - tmp[0] = 0x00; - tmp[1] = tag[17]; - tmp[2] = tag[18]; - tmp[3] = tag[19]; + tmp[0] = 0x00; + tmp[1] = tag[17]; + tmp[2] = tag[18]; + tmp[3] = tag[19]; phTag.PrevBlock = BigEndianBitConverter.ToUInt32(tmp, 0); - phTag.IsLast = phTag.NextBlock == 0xFFFFFF; + phTag.IsLast = phTag.NextBlock == 0xFFFFFF; phTag.IsFirst = phTag.PrevBlock == 0xFFFFFF; return phTag; @@ -256,38 +467,38 @@ namespace DiscImageChef.Decoders byte[] tmp = new byte[4]; - pmTag.Version = BigEndianBitConverter.ToUInt16(tag, 0); - pmTag.Kind = (byte)((tag[2] & 0xC0) >> 6); - pmTag.Reserved = (byte)(tag[2] & 0x3F); - pmTag.Volume = tag[3]; - pmTag.FileId = BigEndianBitConverter.ToInt16(tag, 4); - pmTag.ValidChk |= (tag[6] & 0x80) == 0x80; - pmTag.UsedBytes = (ushort)(BigEndianBitConverter.ToUInt16(tag, 6) & 0x7FFF); + pmTag.Version = BigEndianBitConverter.ToUInt16(tag, 0); + pmTag.Kind = (byte)((tag[2] & 0xC0) >> 6); + pmTag.Reserved = (byte)(tag[2] & 0x3F); + pmTag.Volume = tag[3]; + pmTag.FileId = BigEndianBitConverter.ToInt16(tag, 4); + pmTag.ValidChk |= (tag[6] & 0x80) == 0x80; + pmTag.UsedBytes = (ushort)(BigEndianBitConverter.ToUInt16(tag, 6) & 0x7FFF); - tmp[0] = 0x00; - tmp[1] = tag[8]; - tmp[2] = tag[9]; - tmp[3] = tag[10]; + tmp[0] = 0x00; + tmp[1] = tag[8]; + tmp[2] = tag[9]; + tmp[3] = tag[10]; pmTag.AbsPage = BigEndianBitConverter.ToUInt32(tmp, 0); pmTag.Checksum = tag[11]; - pmTag.RelPage = BigEndianBitConverter.ToUInt16(tag, 12); + pmTag.RelPage = BigEndianBitConverter.ToUInt16(tag, 12); - tmp[0] = 0x00; - tmp[1] = tag[14]; - tmp[2] = tag[15]; - tmp[3] = tag[16]; + tmp[0] = 0x00; + tmp[1] = tag[14]; + tmp[2] = tag[15]; + tmp[3] = tag[16]; pmTag.NextBlock = BigEndianBitConverter.ToUInt32(tmp, 0); - tmp[0] = 0x00; - tmp[1] = tag[17]; - tmp[2] = tag[18]; - tmp[3] = tag[19]; + tmp[0] = 0x00; + tmp[1] = tag[17]; + tmp[2] = tag[18]; + tmp[3] = tag[19]; pmTag.PrevBlock = BigEndianBitConverter.ToUInt32(tmp, 0); pmTag.DiskSize = BigEndianBitConverter.ToUInt32(tag, 20); - pmTag.IsLast = pmTag.NextBlock == 0xFFFFFF; + pmTag.IsLast = pmTag.NextBlock == 0xFFFFFF; pmTag.IsFirst = pmTag.PrevBlock == 0xFFFFFF; return pmTag; @@ -306,22 +517,22 @@ namespace DiscImageChef.Decoders if(snTag == null) return null; - pmTag = new PriamTag(); - pmTag.AbsPage = 0; - pmTag.Checksum = 0; - pmTag.DiskSize = 0; - pmTag.FileId = snTag.Value.FileId; - pmTag.Kind = snTag.Value.Kind; + pmTag = new PriamTag(); + pmTag.AbsPage = 0; + pmTag.Checksum = 0; + pmTag.DiskSize = 0; + pmTag.FileId = snTag.Value.FileId; + pmTag.Kind = snTag.Value.Kind; pmTag.NextBlock = snTag.Value.NextBlock; pmTag.PrevBlock = snTag.Value.PrevBlock; - pmTag.RelPage = snTag.Value.RelPage; - pmTag.Reserved = snTag.Value.Reserved; + pmTag.RelPage = snTag.Value.RelPage; + pmTag.Reserved = snTag.Value.Reserved; pmTag.UsedBytes = 0; - pmTag.ValidChk = false; - pmTag.Version = snTag.Value.Version; - pmTag.Volume = snTag.Value.Volume; - pmTag.IsFirst = snTag.Value.IsFirst; - pmTag.IsLast = snTag.Value.IsLast; + pmTag.ValidChk = false; + pmTag.Version = snTag.Value.Version; + pmTag.Volume = snTag.Value.Volume; + pmTag.IsFirst = snTag.Value.IsFirst; + pmTag.IsLast = snTag.Value.IsLast; return pmTag; case 20: @@ -329,22 +540,22 @@ namespace DiscImageChef.Decoders if(phTag == null) return null; - pmTag = new PriamTag(); - pmTag.AbsPage = phTag.Value.AbsPage; - pmTag.Checksum = phTag.Value.Checksum; - pmTag.DiskSize = 0; - pmTag.FileId = phTag.Value.FileId; - pmTag.Kind = phTag.Value.Kind; + pmTag = new PriamTag(); + pmTag.AbsPage = phTag.Value.AbsPage; + pmTag.Checksum = phTag.Value.Checksum; + pmTag.DiskSize = 0; + pmTag.FileId = phTag.Value.FileId; + pmTag.Kind = phTag.Value.Kind; pmTag.NextBlock = phTag.Value.NextBlock; pmTag.PrevBlock = phTag.Value.PrevBlock; - pmTag.RelPage = phTag.Value.RelPage; - pmTag.Reserved = phTag.Value.Reserved; + pmTag.RelPage = phTag.Value.RelPage; + pmTag.Reserved = phTag.Value.Reserved; pmTag.UsedBytes = phTag.Value.UsedBytes; - pmTag.ValidChk = phTag.Value.ValidChk; - pmTag.Version = phTag.Value.Version; - pmTag.Volume = phTag.Value.Volume; - pmTag.IsFirst = phTag.Value.IsFirst; - pmTag.IsLast = phTag.Value.IsLast; + pmTag.ValidChk = phTag.Value.ValidChk; + pmTag.Version = phTag.Value.Version; + pmTag.Volume = phTag.Value.Volume; + pmTag.IsFirst = phTag.Value.IsFirst; + pmTag.IsLast = phTag.Value.IsLast; return pmTag; case 24: return DecodePriamTag(tag);