add VAG decoder.
This commit is contained in:
parent
71a888d526
commit
2379bf30e7
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
|
||||
</startup>
|
||||
</configuration>
|
||||
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7"/></startup>
|
||||
</configuration>
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using General;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
|
||||
namespace CXML
|
||||
{
|
||||
|
||||
enum AttributeType
|
||||
{
|
||||
TYPE_NONE,
|
||||
|
@ -26,216 +28,10 @@ namespace CXML
|
|||
TYPE_ID_INT
|
||||
};
|
||||
|
||||
|
||||
class Tools
|
||||
{
|
||||
public static String RemoveDecimals(float FloatValue)
|
||||
{
|
||||
String FloatStr = FloatValue.ToString();
|
||||
String[] FloatParts = FloatStr.Split('.');
|
||||
if (FloatParts.Length > 1)
|
||||
if(FloatParts[1].Length > 2)
|
||||
FloatParts[1] = FloatParts[1].Substring(0, 2);
|
||||
|
||||
|
||||
FloatStr = String.Join(".", FloatParts);
|
||||
return FloatStr;
|
||||
}
|
||||
public static MemoryStream ByteToStream(byte[] Array)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
ms.Write(Array, 0x00, Array.Length);
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
return ms;
|
||||
}
|
||||
|
||||
public static byte[] StreamToByte(Stream stream)
|
||||
{
|
||||
int StreamLen = (int)stream.Length;
|
||||
byte[] Bytes = new byte[StreamLen];
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
stream.Read(Bytes, 0x00, StreamLen);
|
||||
return Bytes;
|
||||
}
|
||||
|
||||
public static string GetFileExtension(byte[] Bytes)
|
||||
{
|
||||
if(IsImage(Bytes))
|
||||
{
|
||||
return ".png";
|
||||
}
|
||||
else if(IsZlib(Bytes))
|
||||
{
|
||||
return ".zlib";
|
||||
}
|
||||
else if(IsGim(Bytes))
|
||||
{
|
||||
return ".gim";
|
||||
}
|
||||
else if(IsRcf(Bytes))
|
||||
{
|
||||
return ".rcs";
|
||||
}
|
||||
else if(IsDDS(Bytes))
|
||||
{
|
||||
return ".dds";
|
||||
}
|
||||
else if (IsVAG(Bytes))
|
||||
{
|
||||
return ".vag";
|
||||
}
|
||||
else
|
||||
{
|
||||
return ".bin";
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsVAG(byte[] Bytes)
|
||||
{
|
||||
MemoryStream Data = ByteToStream(Bytes);
|
||||
String header = ReadString(Data, 4);
|
||||
if (header.StartsWith("VAG"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsDDS(byte[] Bytes)
|
||||
{
|
||||
MemoryStream Data = ByteToStream(Bytes);
|
||||
String header = ReadString(Data, 4);
|
||||
if (header.StartsWith("DDS"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool IsRcf(byte[] Bytes)
|
||||
{
|
||||
MemoryStream Data = ByteToStream(Bytes);
|
||||
String header = ReadString(Data, 5);
|
||||
if (header.StartsWith("RCSF"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsGim(byte[] Bytes)
|
||||
{
|
||||
MemoryStream Data = ByteToStream(Bytes);
|
||||
String header = ReadString(Data,4);
|
||||
if(header.StartsWith("MIG"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsZlib(byte[] Bytes)
|
||||
{
|
||||
if(Bytes[0] == 0x78)
|
||||
{
|
||||
if (Bytes[1] == 0x01)
|
||||
return true;
|
||||
if (Bytes[1] == 0x9C)
|
||||
return true;
|
||||
if (Bytes[1] == 0xDA)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static bool IsImage(byte[] Bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetBitmap(Bytes);
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Bitmap GetBitmap(byte[] BitmapBytes)
|
||||
{
|
||||
MemoryStream ms = ByteToStream(BitmapBytes);
|
||||
Bitmap bmp = new Bitmap(ms);
|
||||
ms.Dispose();
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static String ReadStringAt(Stream ms, int location)
|
||||
{
|
||||
long ogPos = ms.Position;
|
||||
ms.Seek(location, SeekOrigin.Begin);
|
||||
String str = ReadString(ms);
|
||||
ms.Seek(ogPos, SeekOrigin.Begin);
|
||||
return str;
|
||||
}
|
||||
|
||||
public static int ReadIntAt(Stream ms, int location)
|
||||
{
|
||||
BinaryReader BinReader = new BinaryReader(ms);
|
||||
long ogPos = ms.Position;
|
||||
ms.Seek(location, SeekOrigin.Begin);
|
||||
int i = BinReader.ReadInt32();
|
||||
ms.Seek(ogPos, SeekOrigin.Begin);
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int ReadInt(Stream ms)
|
||||
{
|
||||
BinaryReader BinReader = new BinaryReader(ms);
|
||||
int i = BinReader.ReadInt32();
|
||||
return i;
|
||||
}
|
||||
|
||||
public static String ReadString(Stream ms, int limit = -1)
|
||||
{
|
||||
int i = 0xFF;
|
||||
|
||||
MemoryStream StringStream = new MemoryStream();
|
||||
|
||||
do
|
||||
{
|
||||
i = ms.ReadByte();
|
||||
if (i == 0 && i != limit)
|
||||
break;
|
||||
StringStream.WriteByte((byte)i);
|
||||
}
|
||||
while (true);
|
||||
|
||||
byte[] StringData = StringStream.ToArray();
|
||||
|
||||
String str = Encoding.UTF8.GetString(StringData);
|
||||
|
||||
return str;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Parser
|
||||
{
|
||||
private bool DECODE_VAG = true;
|
||||
private bool DECODE_GIM = true;
|
||||
|
||||
private static bool _checkMagicNumber()
|
||||
{
|
||||
|
@ -532,6 +328,48 @@ namespace CXML
|
|||
Term();
|
||||
}
|
||||
|
||||
public static void ProcessFile(String FileName)
|
||||
{
|
||||
String Extension = Path.GetExtension(FileName);
|
||||
|
||||
if (Extension == ".vag") //Remove this IF statment if you dont want VAG Conversion.
|
||||
{
|
||||
Console.WriteLine("Decoding: " + Path.GetFileName(FileName));
|
||||
byte[] WaveData = VAG.VAGAudio.Vag2Wav(FileName);
|
||||
String WaveName = Path.GetFileNameWithoutExtension(FileName) + "-" + VAG.VAGAudio.GetFilename(FileName) + ".wav";
|
||||
|
||||
if (!Directory.Exists("files/converted/VAGtoWAV"))
|
||||
Directory.CreateDirectory("files/converted/VAGtoWAV");
|
||||
|
||||
File.WriteAllBytes("files/converted/VAGtoWAV/" + WaveName, WaveData);
|
||||
Console.WriteLine("Decoded file written to: " + WaveName);
|
||||
}
|
||||
if (Extension == ".gim") //Remove this IF statement if you dont want GIM Conversion.
|
||||
{
|
||||
if (File.Exists("GimConv/GimConv.exe"))
|
||||
{
|
||||
if (!Directory.Exists("files/converted"))
|
||||
Directory.CreateDirectory("files/converted/GIMtoPNG");
|
||||
|
||||
Console.WriteLine("Decoding GIM.");
|
||||
|
||||
Process Proc = new Process();
|
||||
Proc.StartInfo.FileName = "GimConv/GimConv.exe";
|
||||
Proc.StartInfo.Arguments = Path.GetFileName(FileName) + " -o " + "../converted/GIMtoPNG/" + Path.GetFileName(Path.ChangeExtension(FileName, "png"));
|
||||
Proc.StartInfo.RedirectStandardOutput = true;
|
||||
Proc.StartInfo.RedirectStandardError = true;
|
||||
Proc.StartInfo.UseShellExecute = false;
|
||||
Proc.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory() + "/files/decompressed";
|
||||
Proc.Start();
|
||||
Proc.WaitForExit();
|
||||
Console.WriteLine(Proc.StandardOutput.ReadToEnd());
|
||||
|
||||
Console.WriteLine("Done!");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReadAttribute(String ElementName = "")
|
||||
{
|
||||
int AttributePtr = bTreeTable.ReadInt32();
|
||||
|
@ -651,35 +489,13 @@ namespace CXML
|
|||
Directory.CreateDirectory("files/decompressed");
|
||||
String DecompressedFilename = "files/decompressed/" + ElementName + "-" + AttributeName + CounterStr + Extension;
|
||||
Console.WriteLine("Decompressed file written to: " + DecompressedFilename);
|
||||
|
||||
File.WriteAllBytes(DecompressedFilename, DecompressedData);
|
||||
|
||||
if(Extension == ".gim")
|
||||
{
|
||||
if(File.Exists("GimConv/GimConv.exe"))
|
||||
{
|
||||
if (!Directory.Exists("files/converted"))
|
||||
Directory.CreateDirectory("files/converted");
|
||||
|
||||
Console.WriteLine("Decoding GIM.");
|
||||
|
||||
Process Proc = new Process();
|
||||
Proc.StartInfo.FileName = "GimConv/GimConv.exe";
|
||||
Proc.StartInfo.Arguments = Path.GetFileName(DecompressedFilename) + " -o " + "../converted/" + ElementName + "-" + AttributeName + CounterStr + ".png";
|
||||
Proc.StartInfo.RedirectStandardOutput = true;
|
||||
Proc.StartInfo.RedirectStandardError = true;
|
||||
Proc.StartInfo.UseShellExecute = false;
|
||||
Proc.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory()+ "/files/decompressed";
|
||||
Proc.Start();
|
||||
Proc.WaitForExit();
|
||||
Console.WriteLine(Proc.StandardOutput.ReadToEnd());
|
||||
|
||||
Console.WriteLine("Done!");
|
||||
}
|
||||
|
||||
}
|
||||
ProcessFile(DecompressedFilename);
|
||||
}
|
||||
|
||||
|
||||
File.WriteAllBytes(FileName, FileData);
|
||||
ProcessFile(FileName);
|
||||
|
||||
AttributeValue = FileName;
|
||||
break;
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>CXMLDecompiler</RootNamespace>
|
||||
<AssemblyName>CXMLDecompiler</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
|
@ -22,6 +23,7 @@
|
|||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
|
@ -31,6 +33,47 @@
|
|||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="DotNetZip, Version=1.13.3.0, Culture=neutral, PublicKeyToken=6583c7c814667745, processorArchitecture=MSIL">
|
||||
|
@ -50,6 +93,8 @@
|
|||
<Compile Include="CXML.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Tools.cs" />
|
||||
<Compile Include="VAG.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using General;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
|
@ -8,7 +9,6 @@ namespace CXMLCli
|
|||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
|
||||
bool Check = true;
|
||||
|
||||
if (args.Length == 0)
|
||||
|
@ -16,8 +16,9 @@ namespace CXMLCli
|
|||
Console.WriteLine("-- app.info/CXML Decompiler --");
|
||||
Console.WriteLine("I like to see girls die :3");
|
||||
Console.WriteLine("Required Arguments:");
|
||||
Console.WriteLine("\t<file>");
|
||||
Console.WriteLine("\t<input_filename>");
|
||||
Console.WriteLine("Optional Arguments:");
|
||||
Console.WriteLine("\t-iv --is-vag File is HE-VAG audio and NOT CXML");
|
||||
Console.WriteLine("\t-f --force Dont check magic number.");
|
||||
Console.WriteLine("\t-dt --dump-tables Dump ALL tables.");
|
||||
Console.WriteLine("\t-tt --dump-tree Dump tree table.");
|
||||
|
@ -37,8 +38,20 @@ namespace CXMLCli
|
|||
|
||||
String ArgsFull = String.Join(" ", args);
|
||||
String path = args[0];
|
||||
|
||||
|
||||
if (ArgsFull.Contains("-iv") || ArgsFull.Contains("--is-vag"))
|
||||
{
|
||||
byte[] WaveData = VAG.VAGAudio.Vag2Wav(path);
|
||||
string FileName = Path.GetFileNameWithoutExtension(path) + "-" + VAG.VAGAudio.GetFilename(path) + ".wav";
|
||||
Console.WriteLine("Writing "+FileName);
|
||||
File.WriteAllBytes(FileName, WaveData);
|
||||
return;
|
||||
}
|
||||
|
||||
CXML.Parser.Init(path, Check);
|
||||
|
||||
|
||||
if (ArgsFull.Contains("-f") || ArgsFull.Contains("--force"))
|
||||
{
|
||||
Check = false;
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace General
|
||||
{
|
||||
class Tools
|
||||
{
|
||||
public static String RemoveDecimals(float FloatValue)
|
||||
{
|
||||
String FloatStr = FloatValue.ToString();
|
||||
String[] FloatParts = FloatStr.Split('.');
|
||||
if (FloatParts.Length > 1)
|
||||
if (FloatParts[1].Length > 2)
|
||||
FloatParts[1] = FloatParts[1].Substring(0, 2);
|
||||
|
||||
|
||||
FloatStr = String.Join(".", FloatParts);
|
||||
return FloatStr;
|
||||
}
|
||||
public static void WriteStringToStream(Stream s, String str)
|
||||
{
|
||||
Byte[] bytes = Encoding.UTF8.GetBytes(str);
|
||||
s.Write(bytes, 0x00, bytes.Length);
|
||||
}
|
||||
public static MemoryStream ByteToStream(byte[] Array)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
ms.Write(Array, 0x00, Array.Length);
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
return ms;
|
||||
}
|
||||
|
||||
public static byte[] StreamToByte(Stream stream)
|
||||
{
|
||||
int StreamLen = (int)stream.Length;
|
||||
byte[] Bytes = new byte[StreamLen];
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
stream.Read(Bytes, 0x00, StreamLen);
|
||||
return Bytes;
|
||||
}
|
||||
|
||||
public static string GetFileExtension(byte[] Bytes)
|
||||
{
|
||||
if (IsImage(Bytes))
|
||||
{
|
||||
return ".png";
|
||||
}
|
||||
else if (IsZlib(Bytes))
|
||||
{
|
||||
return ".zlib";
|
||||
}
|
||||
else if (IsGim(Bytes))
|
||||
{
|
||||
return ".gim";
|
||||
}
|
||||
else if (IsRcf(Bytes))
|
||||
{
|
||||
return ".rcs";
|
||||
}
|
||||
else if (IsDDS(Bytes))
|
||||
{
|
||||
return ".dds";
|
||||
}
|
||||
else if (IsVAG(Bytes))
|
||||
{
|
||||
return ".vag";
|
||||
}
|
||||
else
|
||||
{
|
||||
return ".bin";
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsVAG(byte[] Bytes)
|
||||
{
|
||||
MemoryStream Data = ByteToStream(Bytes);
|
||||
String header = ReadString(Data, 4);
|
||||
if (header.StartsWith("VAG"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsDDS(byte[] Bytes)
|
||||
{
|
||||
MemoryStream Data = ByteToStream(Bytes);
|
||||
String header = ReadString(Data, 4);
|
||||
if (header.StartsWith("DDS"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static bool IsRcf(byte[] Bytes)
|
||||
{
|
||||
MemoryStream Data = ByteToStream(Bytes);
|
||||
String header = ReadString(Data, 5);
|
||||
if (header.StartsWith("RCSF"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsGim(byte[] Bytes)
|
||||
{
|
||||
MemoryStream Data = ByteToStream(Bytes);
|
||||
String header = ReadString(Data, 4);
|
||||
if (header.StartsWith("MIG"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsZlib(byte[] Bytes)
|
||||
{
|
||||
if (Bytes[0] == 0x78)
|
||||
{
|
||||
if (Bytes[1] == 0x01)
|
||||
return true;
|
||||
if (Bytes[1] == 0x9C)
|
||||
return true;
|
||||
if (Bytes[1] == 0xDA)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static bool IsImage(byte[] Bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetBitmap(Bytes);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Bitmap GetBitmap(byte[] BitmapBytes)
|
||||
{
|
||||
MemoryStream ms = ByteToStream(BitmapBytes);
|
||||
Bitmap bmp = new Bitmap(ms);
|
||||
ms.Dispose();
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static String ReadStringAt(Stream ms, int location)
|
||||
{
|
||||
long ogPos = ms.Position;
|
||||
ms.Seek(location, SeekOrigin.Begin);
|
||||
String str = ReadString(ms);
|
||||
ms.Seek(ogPos, SeekOrigin.Begin);
|
||||
return str;
|
||||
}
|
||||
|
||||
public static int ReadIntAt(Stream ms, int location)
|
||||
{
|
||||
BinaryReader BinReader = new BinaryReader(ms);
|
||||
long ogPos = ms.Position;
|
||||
ms.Seek(location, SeekOrigin.Begin);
|
||||
int i = BinReader.ReadInt32();
|
||||
ms.Seek(ogPos, SeekOrigin.Begin);
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int ReadInt(Stream ms)
|
||||
{
|
||||
BinaryReader BinReader = new BinaryReader(ms);
|
||||
int i = BinReader.ReadInt32();
|
||||
return i;
|
||||
}
|
||||
|
||||
public static String ReadString(Stream ms, int limit = -1)
|
||||
{
|
||||
int i = 0xFF;
|
||||
|
||||
MemoryStream StringStream = new MemoryStream();
|
||||
|
||||
do
|
||||
{
|
||||
i = ms.ReadByte();
|
||||
if (i == 0 && i != limit)
|
||||
break;
|
||||
StringStream.WriteByte((byte)i);
|
||||
}
|
||||
while (true);
|
||||
|
||||
byte[] StringData = StringStream.ToArray();
|
||||
|
||||
String str = Encoding.UTF8.GetString(StringData);
|
||||
|
||||
return str;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,357 @@
|
|||
/*
|
||||
|
||||
Based on daemon1's HEVAG decoder
|
||||
(i decompiled his xD)
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using General;
|
||||
|
||||
namespace VAG
|
||||
{
|
||||
class VAGAudio
|
||||
{
|
||||
static int[,] HEVAGCoeffTable = new int[,]
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 7680, 0, 0, 0 },
|
||||
{ 14720, -6656, 0, 0 },
|
||||
{ 12544, -7040, 0, 0 },
|
||||
{ 15616, -7680, 0, 0 },
|
||||
{ 14731, -7059, 0, 0 },
|
||||
{ 14507, -7366, 0, 0 },
|
||||
{ 13920, -7522, 0, 0 },
|
||||
{ 13133, -7680, 0, 0 },
|
||||
{ 12028, -7680, 0, 0 },
|
||||
{ 10764, -7680, 0, 0 },
|
||||
{ 9359, -7680, 0, 0 },
|
||||
{ 7832, -7680, 0, 0 },
|
||||
{ 6201, -7680, 0, 0 },
|
||||
{ 4488, -7680, 0, 0 },
|
||||
{ 2717, -7680, 0, 0 },
|
||||
{ 910, -7680, 0, 0 },
|
||||
{ -910, -7680, 0, 0 },
|
||||
{ -2717, -7680, 0, 0 },
|
||||
{ -4488, -7680, 0, 0 },
|
||||
{ -6201, -7680, 0, 0 },
|
||||
{ -7832, -7680, 0, 0 },
|
||||
{ -9359, -7680, 0, 0 },
|
||||
{ -10764, -7680, 0, 0 },
|
||||
{ -12028, -7680, 0, 0 },
|
||||
{ -13133, -7680, 0, 0 },
|
||||
{ -13920, -7522, 0, 0 },
|
||||
{ -14507, -7366, 0, 0 },
|
||||
{ -14731, -7059, 0, 0 },
|
||||
{ 5376, -9216, 3328, -3072 },
|
||||
{ -6400, -7168, -3328, -2304 },
|
||||
{ -10496, -7424, -3584, -1024 },
|
||||
{ -167, -2722, -494, -541 },
|
||||
{ -7430, -2221, -2298, 424 },
|
||||
{ -8001, -3166, -2814, 289 },
|
||||
{ 6018, -4750, 2649, -1298 },
|
||||
{ 3798, -6946, 3875, -1216 },
|
||||
{ -8237, -2596, -2071, 227 },
|
||||
{ 9199, 1982, -1382, -2316 },
|
||||
{ 13021, -3044, -3792, 1267 },
|
||||
{ 13112, -4487, -2250, 1665 },
|
||||
{ -1668, -3744, -6456, 840 },
|
||||
{ 7819, -4328, 2111, -506 },
|
||||
{ 9571, -1336, -757, 487 },
|
||||
{ 10032, -2562, 300, 199 },
|
||||
{ -4745, -4122, -5486, -1493 },
|
||||
{ -5896, 2378, -4787, -6947 },
|
||||
{ -1193, -9117, -1237, -3114 },
|
||||
{ 2783, -7108, -1575, -1447 },
|
||||
{ -7334, -2062, -2212, 446 },
|
||||
{ 6127, -2577, -315, -18 },
|
||||
{ 9457, -1858, 102, 258 },
|
||||
{ 7876, -4483, 2126, -538 },
|
||||
{ -7172, -1795, -2069, 482 },
|
||||
{ -7358, -2102, -2233, 440 },
|
||||
{ -9170, -3509, -2674, -391 },
|
||||
{ -2638, -2647, -1929, -1637 },
|
||||
{ 1873, 9183, 1860, -5746 },
|
||||
{ 9214, 1859, -1124, -2427 },
|
||||
{ 13204, -3012, -4139, 1370 },
|
||||
{ 12437, -4792, -256, 622 },
|
||||
{ -2653, -1144, -3182, -6878 },
|
||||
{ 9331, -1048, -828, 507 },
|
||||
{ 1642, -620, -946, -4229 },
|
||||
{ 4246, -7585, -533, -2259 },
|
||||
{ -8988, -3891, -2807, 44 },
|
||||
{ -2562, -2735, -1730, -1899 },
|
||||
{ 3182, -483, -714, -1421 },
|
||||
{ 7937, -3844, 2821, -1019 },
|
||||
{ 10069, -2609, 314, 195 },
|
||||
{ 8400, -3297, 1551, -155 },
|
||||
{ -8529, -2775, -2432, -336 },
|
||||
{ 9477, -1882, 108, 256 },
|
||||
{ 75, -2241, -298, -6937 },
|
||||
{ -9143, -4160, -2963, 5 },
|
||||
{ -7270, -1958, -2156, 460 },
|
||||
{ -2740, 3745, 5936, -1089 },
|
||||
{ 8993, 1948, -683, -2704 },
|
||||
{ 13101, -2835, -3854, 1055 },
|
||||
{ 9543, -1961, 130, 250 },
|
||||
{ 5272, -4270, 3124, -3157 },
|
||||
{ -7696, -3383, -2907, -456 },
|
||||
{ 7309, 2523, 434, -2461 },
|
||||
{ 10275, -2867, 391, 172 },
|
||||
{ 10940, -3721, 665, 97 },
|
||||
{ 24, -310, -1262, 320 },
|
||||
{ -8122, -2411, -2311, -271 },
|
||||
{ -8511, -3067, -2337, 163 },
|
||||
{ 326, -3846, 419, -933 },
|
||||
{ 8895, 2194, -541, -2880 },
|
||||
{ 12073, -1876, -2017, -601 },
|
||||
{ 8729, -3423, 1674, -169 },
|
||||
{ 12950, -3847, -3007, 1946 },
|
||||
{ 10038, -2570, 302, 198 },
|
||||
{ 9385, -2757, 1008, 41 },
|
||||
{ -4720, -5006, -2852, -1161 },
|
||||
{ 7869, -4326, 2135, -501 },
|
||||
{ 2450, -8597, 1299, -2780 },
|
||||
{ 10192, -2763, 360, 181 },
|
||||
{ 11313, -4213, 833, 53 },
|
||||
{ 10154, -2716, 345, 185 },
|
||||
{ 9638, -1417, -737, 482 },
|
||||
{ 3854, -4554, 2843, -3397 },
|
||||
{ 6699, -5659, 2249, -1074 },
|
||||
{ 11082, -3908, 728, 80 },
|
||||
{ -1026, -9810, -805, -3462 },
|
||||
{ 10396, -3746, 1367, -96 },
|
||||
{ 10287, 988, -1915, -1437 },
|
||||
{ 7953, 3878, -764, -3263 },
|
||||
{ 12689, -3375, -3354, 2079 },
|
||||
{ 6641, 3166, 231, -2089 },
|
||||
{ -2348, -7354, -1944, -4122 },
|
||||
{ 9290, -4039, 1885, -246 },
|
||||
{ 4633, -6403, 1748, -1619 },
|
||||
{ 11247, -4125, 802, 61 },
|
||||
{ 9807, -2284, 219, 222 },
|
||||
{ 9736, -1536, -706, 473 },
|
||||
{ 8440, -3436, 1562, -176 },
|
||||
{ 9307, -1021, -835, 509 },
|
||||
{ 1698, -9025, 688, -3037 },
|
||||
{ 10214, -2791, 368, 179 },
|
||||
{ 8390, 3248, -758, -2989 },
|
||||
{ 7201, 3316, 46, -2614 },
|
||||
{ -88, -7809, -538, -4571 },
|
||||
{ 6193, -5189, 2760, -1245 },
|
||||
{ 12325, -1290, -3284, 253 },
|
||||
{ 13064, -4075, -2824, 1877 },
|
||||
{ 5333, 2999, 775, -1132 },
|
||||
};
|
||||
|
||||
private static byte[] WriteWaveHeader(byte[] PCMData, int channels, int samplerate)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
int FileSize = PCMData.Length;
|
||||
BinaryWriter bw = new BinaryWriter(ms);
|
||||
|
||||
Tools.WriteStringToStream(ms, "RIFF");
|
||||
bw.Write(FileSize + 36);
|
||||
|
||||
Tools.WriteStringToStream(ms, "WAVE");
|
||||
Tools.WriteStringToStream(ms, "fmt ");
|
||||
bw.Write(16);
|
||||
|
||||
bw.Write((short)1);
|
||||
bw.Write((short)channels);
|
||||
bw.Write(samplerate);
|
||||
bw.Write(samplerate * channels * 2);
|
||||
bw.Write((short)(channels * 2));
|
||||
bw.Write((short)16);
|
||||
|
||||
Tools.WriteStringToStream(ms, "data");
|
||||
bw.Write(FileSize);
|
||||
ms.Write(PCMData, 0x00, FileSize);
|
||||
|
||||
ms.Seek(0x00, SeekOrigin.Begin);
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static byte[] Vag2Wav(string VagFile)
|
||||
{
|
||||
byte[] FileData = File.ReadAllBytes(VagFile);
|
||||
if(Tools.IsVAG(FileData))
|
||||
{
|
||||
byte[] PCMData = DecodePCM(FileData);
|
||||
byte[] WAVData = WriteWaveHeader(PCMData, GetChannels(VagFile), GetSampleRate(VagFile));
|
||||
return WAVData;
|
||||
}
|
||||
throw new Exception("Not a VAG file.");
|
||||
}
|
||||
|
||||
public static int GetChannels(string VagFile)
|
||||
{
|
||||
FileStream VagStream = new FileStream(VagFile, FileMode.Open, FileAccess.Read);
|
||||
VagStream.Seek(0x1E, SeekOrigin.Begin);
|
||||
int ChannelCount = VagStream.ReadByte();
|
||||
if (ChannelCount == 0)
|
||||
ChannelCount = 1; //Its most likely mono...
|
||||
VagStream.Close();
|
||||
|
||||
return ChannelCount;
|
||||
}
|
||||
|
||||
public static string GetFilename(string VagFile)
|
||||
{
|
||||
FileStream VagStream = new FileStream(VagFile, FileMode.Open, FileAccess.Read);
|
||||
String FileName = Tools.ReadStringAt(VagStream, 0x20);
|
||||
VagStream.Close();
|
||||
return FileName;
|
||||
}
|
||||
|
||||
public static int GetSampleRate(String VagFile)
|
||||
{
|
||||
FileStream VagStream = new FileStream(VagFile, FileMode.Open, FileAccess.Read);
|
||||
VagStream.Seek(0x12, SeekOrigin.Begin);
|
||||
|
||||
//IDK Either, ask sony why they didnt just use an int16
|
||||
int SampleRate = VagStream.ReadByte() * 256 + VagStream.ReadByte();
|
||||
VagStream.Close();
|
||||
|
||||
return SampleRate;
|
||||
}
|
||||
|
||||
|
||||
public static byte[] DecodePCM(byte[] VagFile)
|
||||
{
|
||||
int Hist = 0;
|
||||
int Hist2 = 0;
|
||||
int Hist3 = 0;
|
||||
int Hist4 = 0;
|
||||
|
||||
MemoryStream VagStream = Tools.ByteToStream(VagFile);
|
||||
BinaryReader VagReader = new BinaryReader(VagStream);
|
||||
|
||||
MemoryStream PCMStream = new MemoryStream();
|
||||
BinaryWriter PCMWriter = new BinaryWriter(PCMStream);
|
||||
|
||||
VagStream.Seek(0x40, SeekOrigin.Begin);
|
||||
|
||||
while (VagStream.Position < VagStream.Length)
|
||||
{
|
||||
byte DecodingCoefficent = VagReader.ReadByte();
|
||||
int ShiftBy = DecodingCoefficent & 0xf;
|
||||
int PredictNr = DecodingCoefficent >> 0x4;
|
||||
byte LoopData = VagReader.ReadByte();
|
||||
PredictNr |= LoopData & 0xF0;
|
||||
int LoopFlag = LoopData & 0xf;
|
||||
if (LoopFlag == 0x7)
|
||||
{
|
||||
VagStream.Seek(14, SeekOrigin.Current);
|
||||
Hist = 0;
|
||||
Hist2 = 0;
|
||||
Hist3 = 0;
|
||||
Hist4 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
for (int i = 0; i < 14; i++)
|
||||
{
|
||||
//First Byte:
|
||||
|
||||
byte ADPCMData = VagReader.ReadByte();
|
||||
int SampleFlags = ADPCMData & 0xF;
|
||||
int Coefficent;
|
||||
int Sample;
|
||||
|
||||
if (SampleFlags > 7)
|
||||
{
|
||||
SampleFlags -= 16;
|
||||
}
|
||||
|
||||
if (PredictNr < 128)
|
||||
{
|
||||
Coefficent = Hist * HEVAGCoeffTable[PredictNr, 0] + Hist2 * HEVAGCoeffTable[PredictNr, 1] + Hist3 * HEVAGCoeffTable[PredictNr, 2] + Hist4 * HEVAGCoeffTable[PredictNr, 3];
|
||||
}
|
||||
else
|
||||
{
|
||||
Coefficent = 0;
|
||||
}
|
||||
|
||||
Sample = Coefficent / 32 + (SampleFlags << 20 - ShiftBy) + 128 >> 8;
|
||||
|
||||
//Apparently unchecked(short) isnt good enough?
|
||||
//I guess it cant be modulo?
|
||||
//IDK im just doing what i saw in the decompiled code.
|
||||
|
||||
if (Sample > 32767)
|
||||
{
|
||||
Sample = 32767;
|
||||
}
|
||||
else if (Sample < -32768)
|
||||
{
|
||||
Sample = -32768;
|
||||
}
|
||||
|
||||
PCMWriter.Write((short)Sample);
|
||||
|
||||
//Second Byte:
|
||||
|
||||
Hist4 = Hist3;
|
||||
Hist3 = Hist2;
|
||||
Hist2 = Hist;
|
||||
Hist = Sample;
|
||||
|
||||
SampleFlags = ADPCMData >> 4;
|
||||
|
||||
if (SampleFlags > 7)
|
||||
{
|
||||
SampleFlags -= 16;
|
||||
}
|
||||
|
||||
if (PredictNr < 128)
|
||||
{
|
||||
Coefficent = Hist * HEVAGCoeffTable[PredictNr, 0] + Hist2 * HEVAGCoeffTable[PredictNr, 1] + Hist3 * HEVAGCoeffTable[PredictNr, 2] + Hist4 * HEVAGCoeffTable[PredictNr, 3];
|
||||
}
|
||||
else
|
||||
{
|
||||
Coefficent = 0;
|
||||
}
|
||||
|
||||
Sample = Coefficent / 32 + (SampleFlags << 20 - ShiftBy) + 128 >> 8;
|
||||
|
||||
if (Sample > 32767)
|
||||
{
|
||||
Sample = 32767;
|
||||
}
|
||||
else if (Sample < -32768)
|
||||
{
|
||||
Sample = -32768;
|
||||
}
|
||||
|
||||
PCMWriter.Write((short)Sample);
|
||||
|
||||
Hist4 = Hist3;
|
||||
Hist3 = Hist2;
|
||||
Hist2 = Hist;
|
||||
Hist = Sample;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PCMStream.Seek(0x00, SeekOrigin.Begin);
|
||||
byte[] PCMData = PCMStream.ToArray();
|
||||
|
||||
VagReader.Close();
|
||||
VagStream.Close();
|
||||
PCMWriter.Close();
|
||||
PCMStream.Close();
|
||||
|
||||
return PCMData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue