initial commit of media shit

This commit is contained in:
louis 2020-02-18 18:44:58 -05:00
commit 8c0a5e3aa7
38 changed files with 9195 additions and 0 deletions

View file

@ -0,0 +1,864 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
//using VGMToolbox.util;
namespace vgm_acb.extract
{
public class CriField
{
public byte Type { set; get; }
public string Name { set; get; }
public object Value { set; get; }
public ulong Offset { set; get; }
public ulong Size { set; get; }
public override string ToString()
{
StringBuilder sb = new StringBuilder();
string value = String.Empty;
sb.AppendFormat("0x{0} {1} {2} = {3}",
this.Offset.ToString("X8"),
this.Type.ToString("X2"),
this.Name,
this.GetStringValue());
return sb.ToString();
}
public string ToString(FileStream fs)
{
StringBuilder sb = new StringBuilder();
string value = String.Empty;
sb.AppendFormat("0x{0} {1} {2} = {3}",
this.Offset.ToString("X8"),
this.Type.ToString("X2"),
this.Name,
this.GetStringValue(fs));
return sb.ToString();
}
public string GetStringValue(FileStream utfStream = null)
{
ulong numericValue;
byte maskedType = (byte)(this.Type & CriUtfTable.COLUMN_TYPE_MASK);
string stringValue = String.Empty;
switch (maskedType)
{
case CriUtfTable.COLUMN_TYPE_DATA:
if (utfStream == null)
{
stringValue = this.Value.ToString();
}
else
{
if (CriUtfTable.IsUtfTable(utfStream, (long)this.Offset))
{
CriUtfTable newUtf = new CriUtfTable();
newUtf.Initialize(utfStream, (long)this.Offset);
}
}
break;
case CriUtfTable.COLUMN_TYPE_STRING:
stringValue = (string)this.Value;
break;
case CriUtfTable.COLUMN_TYPE_FLOAT:
stringValue = Convert.ToSingle(this.Value).ToString();
break;
case CriUtfTable.COLUMN_TYPE_8BYTE:
case CriUtfTable.COLUMN_TYPE_4BYTE2:
case CriUtfTable.COLUMN_TYPE_4BYTE:
case CriUtfTable.COLUMN_TYPE_2BYTE2:
case CriUtfTable.COLUMN_TYPE_2BYTE:
case CriUtfTable.COLUMN_TYPE_1BYTE2:
case CriUtfTable.COLUMN_TYPE_1BYTE:
numericValue = Convert.ToUInt64(this.Value);
stringValue = String.Format("0x{0}", numericValue.ToString("X8"));
break;
}
return stringValue;
}
}
public class CriUtfTocFileInfo
{
public string DirName { set; get; }
public string FileName { set; get; }
public uint FileSize { set; get; }
public uint ExtractSize { set; get; }
public ulong FileOffset { set; get; }
}
public class CriUtfTable
{
// thanks to hcs for all of this!!!
#region Constants
public static readonly byte[] SIGNATURE_BYTES = new byte[] { 0x40, 0x55, 0x54, 0x46 };
public const string LCG_SEED_KEY = "SEED";
public const string LCG_INCREMENT_KEY = "INC";
public const string TEMP_UTF_TABLE_FILE = "VGMT_UTF.BIN";
public const byte COLUMN_STORAGE_MASK = 0xF0;
public const byte COLUMN_STORAGE_PERROW = 0x50;
public const byte COLUMN_STORAGE_CONSTANT = 0x30;
public const byte COLUMN_STORAGE_CONSTANT2 = 0x70;
public const byte COLUMN_STORAGE_ZERO = 0x10;
// I suspect that "type 2" is signed
public const byte COLUMN_TYPE_MASK = 0x0F;
public const byte COLUMN_TYPE_DATA = 0x0B;
public const byte COLUMN_TYPE_STRING = 0x0A;
// 0x09 double?
public const byte COLUMN_TYPE_FLOAT = 0x08;
// 0x07 signed 8byte?
public const byte COLUMN_TYPE_8BYTE = 0x06;
public const byte COLUMN_TYPE_4BYTE2 = 0x05;
public const byte COLUMN_TYPE_4BYTE = 0x04;
public const byte COLUMN_TYPE_2BYTE2 = 0x03;
public const byte COLUMN_TYPE_2BYTE = 0x02;
public const byte COLUMN_TYPE_1BYTE2 = 0x01;
public const byte COLUMN_TYPE_1BYTE = 0x00;
#endregion
#region Members
public string SourceFile { set; get; }
public long BaseOffset { set; get; }
public string UtfTableFile { set; get; }
public byte[] MagicBytes { set; get; }
public bool IsEncrypted { set; get; }
public uint TableSize { set; get; }
public ushort Unknown1 { set; get; }
public uint RowOffset { set; get; }
public uint StringTableOffset { set; get; }
public uint DataOffset { set; get; }
public uint TableNameOffset { set; get; }
public string TableName { set; get; }
public ushort NumberOfFields { set; get; }
public ushort RowSize { set; get; }
public uint NumberOfRows { set; get; }
public Dictionary<string, CriField>[] Rows { set; get; }
public CriUtfReader UtfReader { set; get; }
#endregion
public void Initialize(FileStream fs, long offset)
{
this.SourceFile = fs.Name;
this.BaseOffset = offset;
try
{
this.MagicBytes = ParseFile.ParseSimpleOffset(fs, this.BaseOffset, 4);
// check if file is decrypted and get decryption keys if needed
this.checkEncryption(fs);
// write (decrypted) utf header to file
this.UtfTableFile = this.WriteTableToTempFile(fs, offset);
this.IsEncrypted = false; // since we've decrypted to a temp file
this.UtfReader.IsEncrypted = false;
if (ParseFile.CompareSegment(this.MagicBytes, 0, SIGNATURE_BYTES))
{
using (FileStream utfTableStream = File.Open(this.UtfTableFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
// read header
this.initializeUtfHeader(utfTableStream);
// initialize rows
this.Rows = new Dictionary<string, CriField>[this.NumberOfRows];
// read schema
if (this.TableSize > 0)
{
this.initializeUtfSchema(fs, utfTableStream, 0x20);
}
}
}
else
{
//Dictionary<string, byte> foo = GetKeysForEncryptedUtfTable(this.MagicBytes);
throw new FormatException(String.Format("@UTF signature not found at offset <0x{0}>.", offset.ToString("X8")));
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (!String.IsNullOrEmpty(this.UtfTableFile))
{
File.Delete(this.UtfTableFile);
}
}
}
public override string ToString()
{
CriField field;
StringBuilder sb = new StringBuilder();
using (FileStream fs = File.Open(this.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
for (int i = 0; i < this.Rows.Length; i++)
{
var d = this.Rows[i];
foreach (var key in d.Keys)
{
field = d[key];
sb.AppendLine(field.ToString(fs));
}
}
}
return sb.ToString();
}
private void checkEncryption(FileStream fs)
{
if (ParseFile.CompareSegment(this.MagicBytes, 0, SIGNATURE_BYTES))
{
this.IsEncrypted = false;
this.UtfReader = new CriUtfReader();
}
else
{
this.IsEncrypted = true;
Dictionary<string, byte> lcgKeys = GetKeysForEncryptedUtfTable(this.MagicBytes);
if (lcgKeys.Count != 2)
{
throw new FormatException(String.Format("Unable to decrypt UTF table at offset: 0x{0}", this.BaseOffset.ToString("X8")));
}
else
{
this.UtfReader = new CriUtfReader(lcgKeys[LCG_SEED_KEY], lcgKeys[LCG_INCREMENT_KEY], this.IsEncrypted);
}
this.MagicBytes = this.UtfReader.GetBytes(fs, this.BaseOffset, 4, 0);
}
}
private void initializeUtfHeader(FileStream UtfTableFs)
{
this.TableSize = ParseFile.ReadUintBE(UtfTableFs, 4);
this.Unknown1 = ParseFile.ReadUshortBE(UtfTableFs, 8);
this.RowOffset = (uint)ParseFile.ReadUshortBE(UtfTableFs, 0xA) + 8;
this.StringTableOffset = ParseFile.ReadUintBE(UtfTableFs, 0xC) + 8;
this.DataOffset = ParseFile.ReadUintBE(UtfTableFs, 0x10) + 8;
this.TableNameOffset = ParseFile.ReadUintBE(UtfTableFs, 0x14);
this.TableName = ParseFile.ReadAsciiString(UtfTableFs, this.StringTableOffset + this.TableNameOffset);
this.NumberOfFields = ParseFile.ReadUshortBE(UtfTableFs, 0x18);
this.RowSize = ParseFile.ReadUshortBE(UtfTableFs, 0x1A);
this.NumberOfRows = ParseFile.ReadUintBE(UtfTableFs, 0x1C);
}
private void initializeUtfSchema(FileStream SourceFs, FileStream UtfTableFs, long schemaOffset)
{
long nameOffset;
long constantOffset;
long dataOffset;
long dataSize;
long rowDataOffset;
long rowDataSize;
long currentOffset = schemaOffset;
long currentRowBase;
long currentRowOffset = 0;
CriField field;
for (uint i = 0; i < this.NumberOfRows; i++)
{
//if (i == 0x1a2a)
//{
// int yuuuu = 1;
//}
//try
//{
currentOffset = schemaOffset;
currentRowBase = this.RowOffset + (this.RowSize * i);
currentRowOffset = 0;
this.Rows[i] = new Dictionary<string, CriField>();
// parse fields
for (ushort j = 0; j < this.NumberOfFields; j++)
{
field = new CriField();
field.Type = ParseFile.ReadByte(UtfTableFs, currentOffset);
nameOffset = ParseFile.ReadUintBE(UtfTableFs, currentOffset + 1);
field.Name = ParseFile.ReadAsciiString(UtfTableFs, this.StringTableOffset + nameOffset);
// each row will have a constant
if (((field.Type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_CONSTANT) ||
((field.Type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_CONSTANT2))
{
// capture offset of constant
constantOffset = currentOffset + 5;
// read the constant depending on the type
switch (field.Type & COLUMN_TYPE_MASK)
{
case COLUMN_TYPE_STRING:
dataOffset = ParseFile.ReadUintBE(UtfTableFs, constantOffset);
field.Value = ParseFile.ReadAsciiString(UtfTableFs, this.StringTableOffset + dataOffset);
currentOffset += 4;
break;
case COLUMN_TYPE_8BYTE:
field.Value = ParseFile.ReadUlongBE(UtfTableFs, constantOffset);
currentOffset += 8;
break;
case COLUMN_TYPE_DATA:
dataOffset = ParseFile.ReadUintBE(UtfTableFs, constantOffset);
dataSize = ParseFile.ReadUintBE(UtfTableFs, constantOffset + 4);
field.Offset = (ulong)(this.BaseOffset + this.DataOffset + dataOffset);
field.Size = (ulong)dataSize;
// don't think this is encrypted, need to check
field.Value = ParseFile.ParseSimpleOffset(SourceFs, (long)field.Offset, (int)dataSize);
currentOffset += 8;
break;
case COLUMN_TYPE_FLOAT:
field.Value = ParseFile.ReadFloatBE(UtfTableFs, constantOffset);
currentOffset += 4;
break;
case COLUMN_TYPE_4BYTE2:
field.Value = ParseFile.ReadInt32BE(UtfTableFs, constantOffset);
currentOffset += 4;
break;
case COLUMN_TYPE_4BYTE:
field.Value = ParseFile.ReadUintBE(UtfTableFs, constantOffset);
currentOffset += 4;
break;
case COLUMN_TYPE_2BYTE2:
field.Value = ParseFile.ReadInt16BE(UtfTableFs, constantOffset);
currentOffset += 2;
break;
case COLUMN_TYPE_2BYTE:
field.Value = ParseFile.ReadUshortBE(UtfTableFs, constantOffset);
currentOffset += 2;
break;
case COLUMN_TYPE_1BYTE2:
field.Value = ParseFile.ReadSByte(UtfTableFs, constantOffset);
currentOffset += 1;
break;
case COLUMN_TYPE_1BYTE:
field.Value = ParseFile.ReadByte(UtfTableFs, constantOffset);
currentOffset += 1;
break;
default:
throw new FormatException(String.Format("Unknown COLUMN TYPE at offset: 0x{0}", currentOffset.ToString("X8")));
} // switch (field.Type & COLUMN_TYPE_MASK)
}
else if ((field.Type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_PERROW)
{
// read the constant depending on the type
switch (field.Type & COLUMN_TYPE_MASK)
{
case COLUMN_TYPE_STRING:
rowDataOffset = ParseFile.ReadUintBE(UtfTableFs, currentRowBase + currentRowOffset);
field.Value = ParseFile.ReadAsciiString(UtfTableFs, this.StringTableOffset + rowDataOffset);
currentRowOffset += 4;
break;
case COLUMN_TYPE_8BYTE:
field.Value = ParseFile.ReadUlongBE(UtfTableFs, currentRowBase + currentRowOffset);
currentRowOffset += 8;
break;
case COLUMN_TYPE_DATA:
rowDataOffset = ParseFile.ReadUintBE(UtfTableFs, currentRowBase + currentRowOffset);
rowDataSize = ParseFile.ReadUintBE(UtfTableFs, currentRowBase + currentRowOffset + 4);
field.Offset = (ulong)(this.BaseOffset + this.DataOffset + rowDataOffset);
field.Size = (ulong)rowDataSize;
// don't think this is encrypted
field.Value = ParseFile.ParseSimpleOffset(SourceFs, (long)field.Offset, (int)rowDataSize);
currentRowOffset += 8;
break;
case COLUMN_TYPE_FLOAT:
field.Value = ParseFile.ReadFloatBE(UtfTableFs, currentRowBase + currentRowOffset);
currentRowOffset += 4;
break;
case COLUMN_TYPE_4BYTE2:
field.Value = ParseFile.ReadInt32BE(UtfTableFs, currentRowBase + currentRowOffset);
currentRowOffset += 4;
break;
case COLUMN_TYPE_4BYTE:
field.Value = ParseFile.ReadUintBE(UtfTableFs, currentRowBase + currentRowOffset);
currentRowOffset += 4;
break;
case COLUMN_TYPE_2BYTE2:
field.Value = ParseFile.ReadInt16BE(UtfTableFs, currentRowBase + currentRowOffset);
currentRowOffset += 2;
break;
case COLUMN_TYPE_2BYTE:
field.Value = ParseFile.ReadUshortBE(UtfTableFs, currentRowBase + currentRowOffset);
currentRowOffset += 2;
break;
case COLUMN_TYPE_1BYTE2:
field.Value = ParseFile.ReadSByte(UtfTableFs, currentRowBase + currentRowOffset);
currentRowOffset += 1;
break;
case COLUMN_TYPE_1BYTE:
field.Value = ParseFile.ReadByte(UtfTableFs, currentRowBase + currentRowOffset);
currentRowOffset += 1;
break;
default:
throw new FormatException(String.Format("Unknown COLUMN TYPE at offset: 0x{0}", currentOffset.ToString("X8")));
} // switch (field.Type & COLUMN_TYPE_MASK)
} // if ((fields[i].Type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_CONSTANT)
// add field to dictionary
this.Rows[i].Add(field.Name, field);
// move to next field
currentOffset += 5; // sizeof(CriField.Type + CriField.NameOffset)
} // for (ushort j = 0; j < this.NumberOfFields; j++)
//}
//catch (Exception ex)
//{
// int xxxx = 1;
//}
} // for (uint i = 0; i < this.NumberOfRows; i++)
}
public string WriteTableToTempFile(FileStream fs, long offsetToUtfTable)
{
string pathToUtf = null;
int totalBytesRead = 0;
int maxRead;
byte[] buffer = new byte[Constants.FileReadChunkSize];
int tableSize = (int)this.UtfReader.ReadUint(fs, offsetToUtfTable, 4) + 8;
pathToUtf = Path.Combine(Path.GetTempPath(), TEMP_UTF_TABLE_FILE);
if (this.IsEncrypted)
{
using (FileStream tempStream = File.Open(pathToUtf, FileMode.Create, FileAccess.Write, FileShare.Read))
{
while (totalBytesRead < tableSize)
{
if ((tableSize - totalBytesRead) > buffer.Length)
{
maxRead = buffer.Length;
}
else
{
maxRead = (tableSize - totalBytesRead);
}
buffer = this.UtfReader.GetBytes(fs, offsetToUtfTable, maxRead, totalBytesRead);
tempStream.Write(buffer, 0, maxRead);
totalBytesRead += maxRead;
}
}
}
else
{
if (File.Exists(pathToUtf))
{
File.Delete(pathToUtf);
}
ParseFile.ExtractChunkToFile64(fs, (ulong)offsetToUtfTable, (ulong)tableSize, pathToUtf, false, false);
}
return pathToUtf;
}
public static object GetUtfFieldForRow(CriUtfTable utfTable, int rowIndex, string key)
{
object ret = null;
if (utfTable.Rows.GetLength(0) > rowIndex)
{
if (utfTable.Rows[rowIndex].ContainsKey(key))
{
ret = utfTable.Rows[rowIndex][key].Value;
}
}
return ret;
}
public static ulong GetOffsetForUtfFieldForRow(CriUtfTable utfTable, int rowIndex, string key)
{
ulong ret = 0;
if (utfTable.Rows.GetLength(0) > rowIndex)
{
if (utfTable.Rows[rowIndex].ContainsKey(key))
{
ret = utfTable.Rows[rowIndex][key].Offset;
}
}
return ret;
}
public static ulong GetSizeForUtfFieldForRow(CriUtfTable utfTable, int rowIndex, string key)
{
ulong ret = 0;
if (utfTable.Rows.GetLength(0) > rowIndex)
{
if (utfTable.Rows[rowIndex].ContainsKey(key))
{
ret = utfTable.Rows[rowIndex][key].Size;
}
}
return ret;
}
public static Dictionary<string, byte> GetKeysForEncryptedUtfTable(byte[] encryptedUtfSignature)
{
Dictionary<string, byte> keys = new Dictionary<string, byte>();
byte m, t;
byte[] xorBytes = new byte[SIGNATURE_BYTES.Length];
bool keysFound = false;
for (byte seed = 0; seed <= byte.MaxValue; seed++)
{
if (!keysFound)
{
// match first char
if ((encryptedUtfSignature[0] ^ seed) == SIGNATURE_BYTES[0])
{
for (byte increment = 0; increment <= byte.MaxValue; increment++)
{
if (!keysFound)
{
m = (byte)(seed * increment);
if ((encryptedUtfSignature[1] ^ m) == SIGNATURE_BYTES[1])
{
t = increment;
for (int j = 2; j < SIGNATURE_BYTES.Length; j++)
{
m *= t;
if ((encryptedUtfSignature[j] ^ m) != SIGNATURE_BYTES[j])
{
break;
}
else if (j == (SIGNATURE_BYTES.Length - 1))
{
keys.Add(LCG_SEED_KEY, seed);
keys.Add(LCG_INCREMENT_KEY, increment);
keysFound = true;
}
}
} // if ((encryptedUtfSignature[1] ^ m) == SIGNATURE_BYTES[1])
}
else
{
break;
} // if (!keysFound)
} // for (byte inc = 0; inc <= byte.MaxValue; inc++)
} // if ((encryptedUtfSignature[0] ^ mult) == SIGNATURE_BYTES[0])
} // if (!keysFound)
else
{
break;
}
} // for (byte mult = 0; mult <= byte.MaxValue; mult++)
return keys;
}
public static bool IsUtfTable(FileStream fs, long offset)
{
bool ret = false;
CriUtfTable utf = new CriUtfTable();
utf.SourceFile = fs.Name;
utf.BaseOffset = offset;
try
{
utf.MagicBytes = ParseFile.ParseSimpleOffset(fs, utf.BaseOffset, 4);
// check if file is decrypted and get decryption keys if needed
utf.checkEncryption(fs);
// write (decrypted) utf header to file
utf.UtfTableFile = utf.WriteTableToTempFile(fs, offset);
utf.IsEncrypted = false; // since we've decrypted to a temp file
utf.UtfReader.IsEncrypted = false;
if (ParseFile.CompareSegment(utf.MagicBytes, 0, SIGNATURE_BYTES))
{
ret = true;
}
else
{
ret = false;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (!String.IsNullOrEmpty(utf.UtfTableFile))
{
File.Delete(utf.UtfTableFile);
}
}
return ret;
}
}
public class CriUtfReader
{
public byte Seed { set; get; }
public byte Increment { set; get; }
public bool IsEncrypted { set; get; }
public byte CurrentXor { set; get; }
public long CurrentUtfOffset { set; get; }
public byte CurrentStringXor { set; get; }
public long CurrentUtfStringOffset { set; get; }
public CriUtfReader()
{
this.IsEncrypted = false;
}
public CriUtfReader(byte seed, byte increment, bool isEncrypted)
{
this.Seed = seed;
this.Increment = increment;
this.IsEncrypted = isEncrypted;
}
public byte[] GetBytes(FileStream fs, long BaseOffset, int Size, long UtfOffset)
{
byte[] ret;
ret = ParseFile.ParseSimpleOffset(fs, BaseOffset + UtfOffset, Size);
if (this.IsEncrypted)
{
if (UtfOffset < this.CurrentUtfOffset)
{
// reset, maybe add some sort of index later?
this.CurrentUtfOffset = 0;
}
if (this.CurrentUtfOffset == 0)
{
// reset or initialize
this.CurrentXor = this.Seed;
}
// catch up to this offset
for (long j = this.CurrentUtfOffset; j < UtfOffset; j++)
{
if (j > 0)
{
this.CurrentXor *= this.Increment;
}
this.CurrentUtfOffset++;
}
// decrypt this offset
for (long i = 0; i < Size; i++)
{
// first byte of UTF table must be XOR'd with the seed
if ((this.CurrentUtfOffset != 0) || (i > 0))
{
this.CurrentXor *= this.Increment;
}
ret[i] ^= this.CurrentXor;
this.CurrentUtfOffset++;
}
}
return ret;
}
public string ReadAsciiString(FileStream fs, long BaseOffset, long UtfOffset)
{
byte encryptedByte;
byte decryptedByte;
StringBuilder asciiVal = new StringBuilder();
byte xorByte;
long fileSize = fs.Length;
if (this.IsEncrypted)
{
fs.Position = (BaseOffset + UtfOffset);
if (UtfOffset < this.CurrentUtfStringOffset)
{
// reset, maybe add some sort of index later?
this.CurrentUtfStringOffset = 0;
}
if (this.CurrentUtfStringOffset == 0)
{
// reset or initialize
this.CurrentStringXor = this.Seed;
}
for (long j = this.CurrentUtfStringOffset; j < UtfOffset; j++)
{
if (j > 0)
{
this.CurrentStringXor *= this.Increment;
}
this.CurrentUtfStringOffset++;
}
for (long i = UtfOffset; i < (fileSize - (BaseOffset + UtfOffset)); i++)
{
this.CurrentStringXor *= this.Increment;
this.CurrentUtfStringOffset++;
encryptedByte = (byte)fs.ReadByte();
decryptedByte = (byte)(encryptedByte ^ this.CurrentStringXor);
if (decryptedByte == 0)
{
break;
}
else
{
asciiVal.Append(Convert.ToChar(decryptedByte));
}
}
}
else
{
asciiVal.Append(ParseFile.ReadAsciiString(fs, BaseOffset + UtfOffset));
}
return asciiVal.ToString();
}
public byte ReadByte(FileStream fs, long BaseOffset, long UtfOffset)
{
return this.GetBytes(fs, BaseOffset, 1, UtfOffset)[0];
}
public SByte ReadSByte(FileStream fs, long BaseOffset, long UtfOffset)
{
return (SByte)this.GetBytes(fs, BaseOffset, 1, UtfOffset)[0];
}
public ushort ReadUshort(FileStream fs, long BaseOffset, long UtfOffset)
{
byte[] temp = this.GetBytes(fs, BaseOffset, 2, UtfOffset);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(temp);
}
return BitConverter.ToUInt16(temp, 0);
}
public short ReadShort(FileStream fs, long BaseOffset, long UtfOffset)
{
byte[] temp = this.GetBytes(fs, BaseOffset, 2, UtfOffset);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(temp);
}
return BitConverter.ToInt16(temp, 0);
}
public uint ReadUint(FileStream fs, long BaseOffset, long UtfOffset)
{
byte[] temp = this.GetBytes(fs, BaseOffset, 4, UtfOffset);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(temp);
}
return BitConverter.ToUInt32(temp, 0);
}
public int ReadInt(FileStream fs, long BaseOffset, long UtfOffset)
{
byte[] temp = this.GetBytes(fs, BaseOffset, 4, UtfOffset);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(temp);
}
return BitConverter.ToInt32(temp, 0);
}
public ulong ReadUlong(FileStream fs, long BaseOffset, long UtfOffset)
{
byte[] temp = this.GetBytes(fs, BaseOffset, 8, UtfOffset);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(temp);
}
return BitConverter.ToUInt64(temp, 0);
}
public float ReadFloat(FileStream fs, long BaseOffset, long UtfOffset)
{
byte[] temp = this.GetBytes(fs, BaseOffset, 4, UtfOffset);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(temp);
}
return BitConverter.ToSingle(temp, 0);
}
}
}