mirror of
https://github.com/crskycode/GARbro.git
synced 2026-07-08 01:30:18 +08:00
Compare commits
29 Commits
GARbro-Mod
...
71a938273f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71a938273f | ||
|
|
bf8e146139 | ||
|
|
6cff1b96d4 | ||
|
|
7ea9381367 | ||
|
|
d4bb9a80fb | ||
|
|
ea9668d68c | ||
|
|
f934d8f3d9 | ||
|
|
b70b1ab498 | ||
|
|
5c8dee7b03 | ||
|
|
e8853332e2 | ||
|
|
0bed7317e7 | ||
|
|
ea358185a6 | ||
|
|
6f2c6fa312 | ||
|
|
d412be39bf | ||
|
|
3107338a3b | ||
|
|
7bb9216fc2 | ||
|
|
cad29fd444 | ||
|
|
515639394a | ||
|
|
dcea49b569 | ||
|
|
95d9be88ff | ||
|
|
ce2507ca58 | ||
|
|
99876cea2a | ||
|
|
fdf5201da4 | ||
|
|
747b0e5009 | ||
|
|
4f7f84ec81 | ||
|
|
a195c676d4 | ||
|
|
4a6962d89e | ||
|
|
08895bdb1c | ||
|
|
69c1970747 |
@@ -268,6 +268,7 @@
|
||||
<Compile Include="Ps1\ImageTIM.cs" />
|
||||
<Compile Include="Psp\ArcGim.cs" />
|
||||
<Compile Include="Psp\ArcQPK.cs" />
|
||||
<Compile Include="QoiCodec.cs" />
|
||||
<Compile Include="ScrPlayer\ImageIMG.cs" />
|
||||
<Compile Include="SingleFileArchive.cs" />
|
||||
<Compile Include="Software House Parsley\ArcCG3.cs" />
|
||||
@@ -278,8 +279,10 @@
|
||||
<Compile Include="VnMaker\AudioMP3.cs" />
|
||||
<Compile Include="VnMaker\AudioOGG.cs" />
|
||||
<Compile Include="VnMaker\ImagePNG.cs" />
|
||||
<Compile Include="WebPCodec.cs" />
|
||||
<Compile Include="Xuse\ArcNT.cs" />
|
||||
<Compile Include="Xuse\ArcWVB.cs" />
|
||||
<Compile Include="YuRis\ImageYDG.cs" />
|
||||
<Compile Include="Zyx\ImageXMG.cs" />
|
||||
<Compile Include="AudioAIFF.cs" />
|
||||
<Compile Include="Basil\ArcMIF.cs" />
|
||||
|
||||
@@ -65,10 +65,10 @@ namespace GameRes.Formats.Artemis
|
||||
data[j] -= (byte)(0x77 * j);
|
||||
var slice_width = 0;
|
||||
var slice_height = 0;
|
||||
if (1 != WebPGetInfo (data, (UIntPtr)data.Length, ref slice_width, ref slice_height))
|
||||
if (1 != WebPCodec.WebPGetInfo(data, (UIntPtr)data.Length, ref slice_width, ref slice_height))
|
||||
throw new InvalidFormatException("WebP image decoder failed.");
|
||||
var slice_size = stride * slice_height;
|
||||
if (IntPtr.Zero == WebPDecodeBGRAInto (data, (UIntPtr)data.Length, output, (UIntPtr)slice_size, stride))
|
||||
if (IntPtr.Zero == WebPCodec.WebPDecodeBGRAInto (data, (UIntPtr)data.Length, output, (UIntPtr)slice_size, stride))
|
||||
throw new InvalidFormatException("WebP image decoder failed.");
|
||||
output += slice_size;
|
||||
}
|
||||
@@ -94,7 +94,7 @@ namespace GameRes.Formats.Artemis
|
||||
offset[i] = file.ReadInt32();
|
||||
for (var i = 0; i < 8; i++)
|
||||
length[i] = file.ReadInt32();
|
||||
LibWebPLoader.Load();
|
||||
WebPCodec.Load();
|
||||
var image_width = 0;
|
||||
var image_height = 0;
|
||||
for (var i = 0; i < 8; i++)
|
||||
@@ -111,7 +111,7 @@ namespace GameRes.Formats.Artemis
|
||||
webp_header[j] -= (byte)(0x77 * j);
|
||||
var slice_width = 0;
|
||||
var slice_height = 0;
|
||||
if (1 != WebPGetInfo (webp_header, (UIntPtr)webp_header.Length, ref slice_width, ref slice_height))
|
||||
if (1 != WebPCodec.WebPGetInfo (webp_header, (UIntPtr)webp_header.Length, ref slice_width, ref slice_height))
|
||||
throw new InvalidFormatException ("WebP image decoder failed.");
|
||||
image_width = Math.Max (image_width, slice_width);
|
||||
image_height += slice_height;
|
||||
@@ -130,36 +130,5 @@ namespace GameRes.Formats.Artemis
|
||||
{
|
||||
throw new NotImplementedException("ImageNekoPNG.Write not implemented");
|
||||
}
|
||||
|
||||
[DllImport("libwebp.dll", EntryPoint = "WebPGetInfo", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int WebPGetInfo ([MarshalAs(UnmanagedType.LPArray)] byte[] data, UIntPtr data_size, ref int width, ref int height);
|
||||
|
||||
[DllImport("libwebp.dll", EntryPoint = "WebPDecodeBGRAInto", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr WebPDecodeBGRAInto ([MarshalAs(UnmanagedType.LPArray)] byte[] data, UIntPtr data_size, IntPtr output_buffer, UIntPtr output_buffer_size, int output_stride);
|
||||
}
|
||||
|
||||
internal static class LibWebPLoader
|
||||
{
|
||||
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
|
||||
static extern IntPtr LoadLibraryEx (string lpFileName, IntPtr hReservedNull, uint dwFlags);
|
||||
|
||||
static bool loaded = false;
|
||||
|
||||
const uint LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100;
|
||||
const uint LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800;
|
||||
|
||||
public static void Load ()
|
||||
{
|
||||
if (loaded)
|
||||
return;
|
||||
var folder = Path.GetDirectoryName (Assembly.GetExecutingAssembly().Location);
|
||||
folder = Path.Combine (folder, (IntPtr.Size == 4) ? "x86" : "x64");
|
||||
var fullPath = Path.Combine (folder, "libwebp.dll");
|
||||
fullPath = Path.GetFullPath (fullPath);
|
||||
var handle = LoadLibraryEx (fullPath, IntPtr.Zero, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (IntPtr.Zero == handle)
|
||||
throw new Win32Exception (Marshal.GetLastWin32Error());
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
dir.Add (new TlgLayerEntry
|
||||
{
|
||||
Name = string.Format ("{0}#{1:D3}.tlg", Path.GetFileNameWithoutExtension (file.Name), i),
|
||||
Offset = 0,
|
||||
Size = (uint)file.MaxOffset,
|
||||
Type = "image",
|
||||
Index = i,
|
||||
|
||||
@@ -53,14 +53,14 @@ namespace GameRes.Formats.KiriKiri
|
||||
public string NamesFile;
|
||||
public Dictionary<string, HxIndexKey> IndexKeyDict;
|
||||
|
||||
public HxCrypt(CxScheme scheme) : base(scheme)
|
||||
public HxCrypt (CxScheme scheme) : base (scheme)
|
||||
{
|
||||
}
|
||||
|
||||
[NonSerialized]
|
||||
uint[] _lookup32 = null;
|
||||
|
||||
void CreateLookup32()
|
||||
void CreateLookup32 ()
|
||||
{
|
||||
if (null != _lookup32)
|
||||
return;
|
||||
@@ -73,7 +73,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
_lookup32 = result;
|
||||
}
|
||||
|
||||
string BinaryToString(byte[] data)
|
||||
string BinaryToString (byte[] data)
|
||||
{
|
||||
if (data.Length == 0)
|
||||
return string.Empty;
|
||||
@@ -88,7 +88,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
return new string(result);
|
||||
}
|
||||
|
||||
internal virtual Dictionary<string, HxEntry> ReadIndex(string arc_name, byte[] data)
|
||||
internal virtual Dictionary<string, HxEntry> ReadIndex (string arc_name, byte[] data)
|
||||
{
|
||||
if (data.Length <= 20) // 16 + 4
|
||||
return null;
|
||||
@@ -123,8 +123,8 @@ namespace GameRes.Formats.KiriKiri
|
||||
if (null == root_obj)
|
||||
return null;
|
||||
CreateLookup32 ();
|
||||
var path_map = new Dictionary<string, string>();
|
||||
var name_map = new Dictionary<string, string>();
|
||||
var path_map = new Dictionary<string, string> ();
|
||||
var name_map = new Dictionary<string, string> ();
|
||||
try
|
||||
{
|
||||
FormatCatalog.Instance.ReadFileList (NamesFile, line => {
|
||||
@@ -138,7 +138,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
});
|
||||
}
|
||||
catch (Exception) { }
|
||||
var entry_info_map = new Dictionary<string, HxEntry>();
|
||||
var entry_info_map = new Dictionary<string, HxEntry> ();
|
||||
for (var i = 0; i < root_obj.Length; i += 2)
|
||||
{
|
||||
var path_hash = root_obj[i] as byte[];
|
||||
@@ -180,7 +180,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
return entry_info_map;
|
||||
}
|
||||
|
||||
internal virtual string GetUnicodeName(uint hash)
|
||||
internal virtual string GetUnicodeName (uint hash)
|
||||
{
|
||||
var buf = new char[4];
|
||||
var i = 0;
|
||||
@@ -195,7 +195,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
return str;
|
||||
}
|
||||
|
||||
internal virtual HxFilterKey CreateFilterKey(ulong entry_key, ulong header_key_seed)
|
||||
internal virtual HxFilterKey CreateFilterKey (ulong entry_key, ulong header_key_seed)
|
||||
{
|
||||
var result = new HxFilterKey
|
||||
{
|
||||
@@ -208,16 +208,16 @@ namespace GameRes.Formats.KiriKiri
|
||||
uint key0 = (uint)(entry_key & 0xffffffff);
|
||||
uint key1 = (uint)((entry_key >> 32) & 0xffffffff);
|
||||
|
||||
var k0 = ExecuteXCode(key0);
|
||||
var k0 = ExecuteXCode (key0);
|
||||
result.Key[0] = (ulong)k0.Item1 | ((ulong)k0.Item2 << 32);
|
||||
var k1 = ExecuteXCode(key1);
|
||||
var k1 = ExecuteXCode (key1);
|
||||
result.Key[1] = (ulong)k1.Item1 | ((ulong)k1.Item2 << 32);
|
||||
|
||||
result.SplitPosition = (long)((this.m_offset + ((entry_key >> 16) & this.m_mask)) & 0xffffffff);
|
||||
|
||||
/* create header key */
|
||||
|
||||
var k3 = ExecuteXCode((uint)header_key_seed);
|
||||
var k3 = ExecuteXCode ((uint)header_key_seed);
|
||||
var v5 = (ulong)k3.Item1 | ((ulong)k3.Item2 << 32);
|
||||
v5 = ~v5;
|
||||
|
||||
@@ -226,7 +226,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
result.HeaderKey[i] = (byte)((v5 >> j) & 0xff);
|
||||
}
|
||||
|
||||
k3 = ExecuteXCode((uint)v5);
|
||||
k3 = ExecuteXCode ((uint)v5);
|
||||
v5 = (ulong)k3.Item1 | ((ulong)k3.Item2 << 32);
|
||||
v5 = ~v5;
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
return result;
|
||||
}
|
||||
|
||||
internal virtual void CreateFilter(Xp3Entry entry)
|
||||
internal virtual void CreateFilter (Xp3Entry entry)
|
||||
{
|
||||
var info = entry.Extra as HxEntry;
|
||||
if (null == info)
|
||||
@@ -256,20 +256,25 @@ namespace GameRes.Formats.KiriKiri
|
||||
info.Filter = new HxFilter (key);
|
||||
}
|
||||
|
||||
public override void Init(ArcFile arc)
|
||||
public override void Init (ArcFile arc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public override byte Decrypt(Xp3Entry entry, long offset, byte value)
|
||||
public override Stream EntryReadFilter (Xp3Entry entry, Stream input)
|
||||
{
|
||||
var info = entry.Extra as HxEntry;
|
||||
if (null == info)
|
||||
return base.EntryReadFilter (entry, input);
|
||||
CreateFilter (entry);
|
||||
return base.EntryReadFilter (entry, input);
|
||||
}
|
||||
|
||||
public override byte Decrypt (Xp3Entry entry, long offset, byte value)
|
||||
{
|
||||
if (entry.Extra == null)
|
||||
return value;
|
||||
var info = entry.Extra as HxEntry;
|
||||
if (null == info)
|
||||
return value;
|
||||
if (null == info.Filter)
|
||||
CreateFilter (entry);
|
||||
if (null == info.Filter)
|
||||
return value;
|
||||
|
||||
@@ -280,15 +285,11 @@ namespace GameRes.Formats.KiriKiri
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
public override void Decrypt(Xp3Entry entry, long offset, byte[] buffer, int pos, int count)
|
||||
public override void Decrypt (Xp3Entry entry, long offset, byte[] buffer, int pos, int count)
|
||||
{
|
||||
if (entry.Extra == null)
|
||||
return;
|
||||
var info = entry.Extra as HxEntry;
|
||||
if (null == info)
|
||||
return;
|
||||
if (null == info.Filter)
|
||||
CreateFilter (entry);
|
||||
if (null == info.Filter)
|
||||
return;
|
||||
|
||||
@@ -297,14 +298,14 @@ namespace GameRes.Formats.KiriKiri
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Encrypt(Xp3Entry entry, long offset, byte[] values, int pos, int count)
|
||||
public override void Encrypt (Xp3Entry entry, long offset, byte[] values, int pos, int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
internal override CxProgram NewProgram(uint seed)
|
||||
internal override CxProgram NewProgram (uint seed)
|
||||
{
|
||||
return new HxProgram(seed, ControlBlock, RandomType);
|
||||
return new HxProgram (seed, ControlBlock, RandomType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,7 +347,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
public long Position;
|
||||
public HxBufferSpan Data;
|
||||
|
||||
bool AdjustHeaderKey(HxHeaderKey key, HxHeaderKey new_key)
|
||||
bool AdjustHeaderKey (HxHeaderKey key, HxHeaderKey new_key)
|
||||
{
|
||||
if (this.Data.Buffer == null)
|
||||
return false;
|
||||
@@ -380,11 +381,11 @@ namespace GameRes.Formats.KiriKiri
|
||||
return true;
|
||||
}
|
||||
|
||||
public void DecryptHeader(HxHeaderKey key)
|
||||
public void DecryptHeader (HxHeaderKey key)
|
||||
{
|
||||
var key2 = new HxHeaderKey();
|
||||
var key2 = new HxHeaderKey ();
|
||||
|
||||
if (AdjustHeaderKey(key, key2))
|
||||
if (AdjustHeaderKey (key, key2))
|
||||
{
|
||||
for (uint i = 0; i < key2.Length; i++)
|
||||
{
|
||||
@@ -394,7 +395,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
}
|
||||
}
|
||||
|
||||
public int Split(long split_position, HxFilterSpan[] sub_span)
|
||||
public int Split (long split_position, HxFilterSpan[] sub_span)
|
||||
{
|
||||
if (this.Data.Buffer == null)
|
||||
return 0;
|
||||
@@ -443,7 +444,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
}
|
||||
}
|
||||
|
||||
public void FirstDecrypt(uint key)
|
||||
public void FirstDecrypt (uint key)
|
||||
{
|
||||
if (this.Data.Buffer == null)
|
||||
return;
|
||||
@@ -451,7 +452,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
if (this.Data.Length == 0)
|
||||
return;
|
||||
|
||||
var buf = BitConverter.GetBytes(key);
|
||||
var buf = BitConverter.GetBytes (key);
|
||||
|
||||
for (int i = 0; i < this.Data.Length; i++)
|
||||
{
|
||||
@@ -467,7 +468,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
private uint FirstDecryptKey;
|
||||
private uint DecryptKey;
|
||||
|
||||
public HxFilterSpanDecryptor(ulong key, bool flag)
|
||||
public HxFilterSpanDecryptor (ulong key, bool flag)
|
||||
{
|
||||
this.DecryptKey = (uint)((key >> 8) & 0xFF);
|
||||
this.DecryptKey |= (uint)((key >> 8) & 0xFF00);
|
||||
@@ -492,9 +493,9 @@ namespace GameRes.Formats.KiriKiri
|
||||
this.FirstDecryptKey *= 0x1010101;
|
||||
}
|
||||
|
||||
public void Decrypt(HxFilterSpan span)
|
||||
public void Decrypt (HxFilterSpan span)
|
||||
{
|
||||
span.FirstDecrypt(FirstDecryptKey);
|
||||
span.FirstDecrypt (FirstDecryptKey);
|
||||
|
||||
byte key1 = (byte)(this.DecryptKey & 0xFF);
|
||||
byte key2 = (byte)((this.DecryptKey >> 8) & 0xFF);
|
||||
@@ -525,17 +526,17 @@ namespace GameRes.Formats.KiriKiri
|
||||
private long SplitPosition;
|
||||
private HxHeaderKey HeaderKey;
|
||||
|
||||
public HxFilter(HxFilterKey key)
|
||||
public HxFilter (HxFilterKey key)
|
||||
{
|
||||
this.Span = new HxFilterSpanDecryptor[2]
|
||||
{
|
||||
new HxFilterSpanDecryptor(key.Key[0], key.Flag),
|
||||
new HxFilterSpanDecryptor(key.Key[1], key.Flag),
|
||||
new HxFilterSpanDecryptor (key.Key[0], key.Flag),
|
||||
new HxFilterSpanDecryptor (key.Key[1], key.Flag),
|
||||
};
|
||||
|
||||
this.SplitPosition = key.SplitPosition;
|
||||
|
||||
this.HeaderKey = new HxHeaderKey();
|
||||
this.HeaderKey = new HxHeaderKey ();
|
||||
|
||||
if (key.HasHeaderKey)
|
||||
{
|
||||
@@ -544,7 +545,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
}
|
||||
}
|
||||
|
||||
public void Decrypt(long position, byte[] buffer, int buffer_ptr, int length)
|
||||
public void Decrypt (long position, byte[] buffer, int buffer_ptr, int length)
|
||||
{
|
||||
var span = new HxFilterSpan
|
||||
{
|
||||
@@ -560,21 +561,21 @@ namespace GameRes.Formats.KiriKiri
|
||||
|
||||
if (span.Position < this.HeaderKey.Position + this.HeaderKey.Length)
|
||||
{
|
||||
span.DecryptHeader(this.HeaderKey);
|
||||
span.DecryptHeader (this.HeaderKey);
|
||||
}
|
||||
|
||||
var sub_span = new HxFilterSpan[2];
|
||||
|
||||
var flags = span.Split(this.SplitPosition, sub_span);
|
||||
var flags = span.Split (this.SplitPosition, sub_span);
|
||||
|
||||
if ((flags & 1) != 0)
|
||||
{
|
||||
this.Span[0].Decrypt(sub_span[0]);
|
||||
this.Span[0].Decrypt (sub_span[0]);
|
||||
}
|
||||
|
||||
if ((flags & 2) != 0)
|
||||
{
|
||||
this.Span[1].Decrypt(sub_span[1]);
|
||||
this.Span[1].Decrypt (sub_span[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -583,12 +584,12 @@ namespace GameRes.Formats.KiriKiri
|
||||
{
|
||||
private ulong m_seed;
|
||||
|
||||
public HxSplittableRandom(ulong seed)
|
||||
public HxSplittableRandom (ulong seed)
|
||||
{
|
||||
m_seed = seed;
|
||||
}
|
||||
|
||||
public ulong Next()
|
||||
public ulong Next ()
|
||||
{
|
||||
ulong z;
|
||||
|
||||
@@ -618,7 +619,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
readonly int m_random_method;
|
||||
new readonly M64[] m_seed;
|
||||
|
||||
public HxProgram(uint seed, uint[] control_block, int random_method) : base(seed, control_block)
|
||||
public HxProgram (uint seed, uint[] control_block, int random_method) : base(seed, control_block)
|
||||
{
|
||||
m_random_method = random_method;
|
||||
m_seed = new M64[2];
|
||||
@@ -628,19 +629,19 @@ namespace GameRes.Formats.KiriKiri
|
||||
|
||||
var r = new HxSplittableRandom(s);
|
||||
|
||||
m_seed[0].u64 = r.Next();
|
||||
m_seed[1].u64 = r.Next();
|
||||
m_seed[0].u64 = r.Next ();
|
||||
m_seed[1].u64 = r.Next ();
|
||||
}
|
||||
|
||||
ulong GetOldRandom()
|
||||
ulong GetOldRandom ()
|
||||
{
|
||||
/* These codes only work correctly in little endian mode! */
|
||||
|
||||
var a = new M64();
|
||||
var b = new M64();
|
||||
var c = new M64();
|
||||
var d = new M64();
|
||||
var e = new M64();
|
||||
var a = new M64 ();
|
||||
var b = new M64 ();
|
||||
var c = new M64 ();
|
||||
var d = new M64 ();
|
||||
var e = new M64 ();
|
||||
|
||||
ulong t;
|
||||
|
||||
@@ -676,14 +677,14 @@ namespace GameRes.Formats.KiriKiri
|
||||
return t;
|
||||
}
|
||||
|
||||
ulong GetNewRandom()
|
||||
ulong GetNewRandom ()
|
||||
{
|
||||
/* These codes only work correctly in little endian mode! */
|
||||
|
||||
var a = new M64();
|
||||
var b = new M64();
|
||||
var c = new M64();
|
||||
var d = new M64();
|
||||
var a = new M64 ();
|
||||
var b = new M64 ();
|
||||
var c = new M64 ();
|
||||
var d = new M64 ();
|
||||
|
||||
ulong t;
|
||||
|
||||
@@ -719,12 +720,12 @@ namespace GameRes.Formats.KiriKiri
|
||||
return t;
|
||||
}
|
||||
|
||||
public override uint GetRandom()
|
||||
public override uint GetRandom ()
|
||||
{
|
||||
if (0 == m_random_method)
|
||||
return (uint)GetOldRandom();
|
||||
return (uint) GetOldRandom ();
|
||||
else
|
||||
return (uint)GetNewRandom();
|
||||
return (uint) GetNewRandom ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,9 +742,9 @@ namespace GameRes.Formats.KiriKiri
|
||||
|
||||
readonly State m_state;
|
||||
|
||||
public HxChachaDecryptor(byte[] key, byte[] nonce, uint[] seed)
|
||||
public HxChachaDecryptor (byte[] key, byte[] nonce, uint[] seed)
|
||||
{
|
||||
m_state = new State();
|
||||
m_state = new State ();
|
||||
|
||||
var constant = Encoding.ASCII.GetBytes ("expand 32-byte k");
|
||||
|
||||
@@ -755,91 +756,91 @@ namespace GameRes.Formats.KiriKiri
|
||||
Array.Copy (nonce, 0, m_state.Data, 56, 8);
|
||||
}
|
||||
|
||||
void TransformState(State src, State dst)
|
||||
void TransformState (State src, State dst)
|
||||
{
|
||||
uint z0, z1, z2, z3, z4, z5, z6, z7,
|
||||
z8, z9, za, zb, zc, zd, ze, zf;
|
||||
|
||||
z0 = LittleEndian.ToUInt32(src.Data, 0);
|
||||
z1 = LittleEndian.ToUInt32(src.Data, 4);
|
||||
z2 = LittleEndian.ToUInt32(src.Data, 8);
|
||||
z3 = LittleEndian.ToUInt32(src.Data, 12);
|
||||
z4 = LittleEndian.ToUInt32(src.Data, 16);
|
||||
z5 = LittleEndian.ToUInt32(src.Data, 20);
|
||||
z6 = LittleEndian.ToUInt32(src.Data, 24);
|
||||
z7 = LittleEndian.ToUInt32(src.Data, 28);
|
||||
z8 = LittleEndian.ToUInt32(src.Data, 32);
|
||||
z9 = LittleEndian.ToUInt32(src.Data, 36);
|
||||
za = LittleEndian.ToUInt32(src.Data, 40);
|
||||
zb = LittleEndian.ToUInt32(src.Data, 44);
|
||||
zc = LittleEndian.ToUInt32(src.Data, 48);
|
||||
zd = LittleEndian.ToUInt32(src.Data, 52);
|
||||
ze = LittleEndian.ToUInt32(src.Data, 56);
|
||||
zf = LittleEndian.ToUInt32(src.Data, 60);
|
||||
z0 = LittleEndian.ToUInt32 (src.Data, 0);
|
||||
z1 = LittleEndian.ToUInt32 (src.Data, 4);
|
||||
z2 = LittleEndian.ToUInt32 (src.Data, 8);
|
||||
z3 = LittleEndian.ToUInt32 (src.Data, 12);
|
||||
z4 = LittleEndian.ToUInt32 (src.Data, 16);
|
||||
z5 = LittleEndian.ToUInt32 (src.Data, 20);
|
||||
z6 = LittleEndian.ToUInt32 (src.Data, 24);
|
||||
z7 = LittleEndian.ToUInt32 (src.Data, 28);
|
||||
z8 = LittleEndian.ToUInt32 (src.Data, 32);
|
||||
z9 = LittleEndian.ToUInt32 (src.Data, 36);
|
||||
za = LittleEndian.ToUInt32 (src.Data, 40);
|
||||
zb = LittleEndian.ToUInt32 (src.Data, 44);
|
||||
zc = LittleEndian.ToUInt32 (src.Data, 48);
|
||||
zd = LittleEndian.ToUInt32 (src.Data, 52);
|
||||
ze = LittleEndian.ToUInt32 (src.Data, 56);
|
||||
zf = LittleEndian.ToUInt32 (src.Data, 60);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
// QUARTER(z0, z4, z8, zc);
|
||||
z0 += z4; zc = Binary.RotL(zc ^ z0, 16);
|
||||
z8 += zc; z4 = Binary.RotL(z4 ^ z8, 12);
|
||||
z0 += z4; zc = Binary.RotL(zc ^ z0, 8);
|
||||
z8 += zc; z4 = Binary.RotL(z4 ^ z8, 7);
|
||||
z0 += z4; zc = Binary.RotL (zc ^ z0, 16);
|
||||
z8 += zc; z4 = Binary.RotL (z4 ^ z8, 12);
|
||||
z0 += z4; zc = Binary.RotL (zc ^ z0, 8);
|
||||
z8 += zc; z4 = Binary.RotL (z4 ^ z8, 7);
|
||||
// QUARTER(z1, z5, z9, zd);
|
||||
z1 += z5; zd = Binary.RotL(zd ^ z1, 16);
|
||||
z9 += zd; z5 = Binary.RotL(z5 ^ z9, 12);
|
||||
z1 += z5; zd = Binary.RotL(zd ^ z1, 8);
|
||||
z9 += zd; z5 = Binary.RotL(z5 ^ z9, 7);
|
||||
z1 += z5; zd = Binary.RotL (zd ^ z1, 16);
|
||||
z9 += zd; z5 = Binary.RotL (z5 ^ z9, 12);
|
||||
z1 += z5; zd = Binary.RotL (zd ^ z1, 8);
|
||||
z9 += zd; z5 = Binary.RotL (z5 ^ z9, 7);
|
||||
// QUARTER(z2, z6, za, ze);
|
||||
z2 += z6; ze = Binary.RotL(ze ^ z2, 16);
|
||||
za += ze; z6 = Binary.RotL(z6 ^ za, 12);
|
||||
z2 += z6; ze = Binary.RotL(ze ^ z2, 8);
|
||||
za += ze; z6 = Binary.RotL(z6 ^ za, 7);
|
||||
z2 += z6; ze = Binary.RotL (ze ^ z2, 16);
|
||||
za += ze; z6 = Binary.RotL (z6 ^ za, 12);
|
||||
z2 += z6; ze = Binary.RotL (ze ^ z2, 8);
|
||||
za += ze; z6 = Binary.RotL (z6 ^ za, 7);
|
||||
// QUARTER(z3, z7, zb, zf);
|
||||
z3 += z7; zf = Binary.RotL(zf ^ z3, 16);
|
||||
zb += zf; z7 = Binary.RotL(z7 ^ zb, 12);
|
||||
z3 += z7; zf = Binary.RotL(zf ^ z3, 8);
|
||||
zb += zf; z7 = Binary.RotL(z7 ^ zb, 7);
|
||||
z3 += z7; zf = Binary.RotL (zf ^ z3, 16);
|
||||
zb += zf; z7 = Binary.RotL (z7 ^ zb, 12);
|
||||
z3 += z7; zf = Binary.RotL (zf ^ z3, 8);
|
||||
zb += zf; z7 = Binary.RotL (z7 ^ zb, 7);
|
||||
// QUARTER(z0, z5, za, zf);
|
||||
z0 += z5; zf = Binary.RotL(zf ^ z0, 16);
|
||||
za += zf; z5 = Binary.RotL(z5 ^ za, 12);
|
||||
z0 += z5; zf = Binary.RotL(zf ^ z0, 8);
|
||||
za += zf; z5 = Binary.RotL(z5 ^ za, 7);
|
||||
z0 += z5; zf = Binary.RotL (zf ^ z0, 16);
|
||||
za += zf; z5 = Binary.RotL (z5 ^ za, 12);
|
||||
z0 += z5; zf = Binary.RotL (zf ^ z0, 8);
|
||||
za += zf; z5 = Binary.RotL (z5 ^ za, 7);
|
||||
// QUARTER(z1, z6, zb, zc);
|
||||
z1 += z6; zc = Binary.RotL(zc ^ z1, 16);
|
||||
zb += zc; z6 = Binary.RotL(z6 ^ zb, 12);
|
||||
z1 += z6; zc = Binary.RotL(zc ^ z1, 8);
|
||||
zb += zc; z6 = Binary.RotL(z6 ^ zb, 7);
|
||||
z1 += z6; zc = Binary.RotL (zc ^ z1, 16);
|
||||
zb += zc; z6 = Binary.RotL (z6 ^ zb, 12);
|
||||
z1 += z6; zc = Binary.RotL (zc ^ z1, 8);
|
||||
zb += zc; z6 = Binary.RotL (z6 ^ zb, 7);
|
||||
// QUARTER(z2, z7, z8, zd);
|
||||
z2 += z7; zd = Binary.RotL(zd ^ z2, 16);
|
||||
z8 += zd; z7 = Binary.RotL(z7 ^ z8, 12);
|
||||
z2 += z7; zd = Binary.RotL(zd ^ z2, 8);
|
||||
z8 += zd; z7 = Binary.RotL(z7 ^ z8, 7);
|
||||
z2 += z7; zd = Binary.RotL (zd ^ z2, 16);
|
||||
z8 += zd; z7 = Binary.RotL (z7 ^ z8, 12);
|
||||
z2 += z7; zd = Binary.RotL (zd ^ z2, 8);
|
||||
z8 += zd; z7 = Binary.RotL (z7 ^ z8, 7);
|
||||
// QUARTER(z3, z4, z9, ze);
|
||||
z3 += z4; ze = Binary.RotL(ze ^ z3, 16);
|
||||
z9 += ze; z4 = Binary.RotL(z4 ^ z9, 12);
|
||||
z3 += z4; ze = Binary.RotL(ze ^ z3, 8);
|
||||
z9 += ze; z4 = Binary.RotL(z4 ^ z9, 7);
|
||||
z3 += z4; ze = Binary.RotL (ze ^ z3, 16);
|
||||
z9 += ze; z4 = Binary.RotL (z4 ^ z9, 12);
|
||||
z3 += z4; ze = Binary.RotL (ze ^ z3, 8);
|
||||
z9 += ze; z4 = Binary.RotL (z4 ^ z9, 7);
|
||||
}
|
||||
|
||||
LittleEndian.Pack(z0, dst.Data, 0);
|
||||
LittleEndian.Pack(z1, dst.Data, 4);
|
||||
LittleEndian.Pack(z2, dst.Data, 8);
|
||||
LittleEndian.Pack(z3, dst.Data, 12);
|
||||
LittleEndian.Pack(z4, dst.Data, 16);
|
||||
LittleEndian.Pack(z5, dst.Data, 20);
|
||||
LittleEndian.Pack(z6, dst.Data, 24);
|
||||
LittleEndian.Pack(z7, dst.Data, 28);
|
||||
LittleEndian.Pack(z8, dst.Data, 32);
|
||||
LittleEndian.Pack(z9, dst.Data, 36);
|
||||
LittleEndian.Pack(za, dst.Data, 40);
|
||||
LittleEndian.Pack(zb, dst.Data, 44);
|
||||
LittleEndian.Pack(zc, dst.Data, 48);
|
||||
LittleEndian.Pack(zd, dst.Data, 52);
|
||||
LittleEndian.Pack(ze, dst.Data, 56);
|
||||
LittleEndian.Pack(zf, dst.Data, 60);
|
||||
LittleEndian.Pack (z0, dst.Data, 0);
|
||||
LittleEndian.Pack (z1, dst.Data, 4);
|
||||
LittleEndian.Pack (z2, dst.Data, 8);
|
||||
LittleEndian.Pack (z3, dst.Data, 12);
|
||||
LittleEndian.Pack (z4, dst.Data, 16);
|
||||
LittleEndian.Pack (z5, dst.Data, 20);
|
||||
LittleEndian.Pack (z6, dst.Data, 24);
|
||||
LittleEndian.Pack (z7, dst.Data, 28);
|
||||
LittleEndian.Pack (z8, dst.Data, 32);
|
||||
LittleEndian.Pack (z9, dst.Data, 36);
|
||||
LittleEndian.Pack (za, dst.Data, 40);
|
||||
LittleEndian.Pack (zb, dst.Data, 44);
|
||||
LittleEndian.Pack (zc, dst.Data, 48);
|
||||
LittleEndian.Pack (zd, dst.Data, 52);
|
||||
LittleEndian.Pack (ze, dst.Data, 56);
|
||||
LittleEndian.Pack (zf, dst.Data, 60);
|
||||
}
|
||||
|
||||
public void Decrypt(byte[] input, int input_pos, byte[] output, int output_pos, int length)
|
||||
public void Decrypt (byte[] input, int input_pos, byte[] output, int output_pos, int length)
|
||||
{
|
||||
var state = new State ();
|
||||
var num_block = length / 64;
|
||||
@@ -893,19 +894,19 @@ namespace GameRes.Formats.KiriKiri
|
||||
|
||||
internal class HxIndexDeserializer
|
||||
{
|
||||
public static object Deserialize(Stream stream)
|
||||
public static object Deserialize (Stream stream)
|
||||
{
|
||||
using (var reader = new BinaryReader(stream, Encoding.ASCII, true))
|
||||
using (var reader = new BinaryReader (stream, Encoding.ASCII, true))
|
||||
{
|
||||
var obj = ReadObject(reader);
|
||||
Debug.Assert(stream.Position == stream.Length);
|
||||
var obj = ReadObject (reader);
|
||||
Debug.Assert (stream.Position == stream.Length);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
static object ReadObject(BinaryReader reader)
|
||||
static object ReadObject (BinaryReader reader)
|
||||
{
|
||||
var type = reader.ReadByte();
|
||||
var type = reader.ReadByte ();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@@ -919,88 +920,88 @@ namespace GameRes.Formats.KiriKiri
|
||||
}
|
||||
case 0x02:
|
||||
{
|
||||
return ReadString(reader);
|
||||
return ReadString (reader);
|
||||
}
|
||||
case 0x03:
|
||||
{
|
||||
return ReadByteArray(reader);
|
||||
return ReadByteArray (reader);
|
||||
}
|
||||
case 0x04:
|
||||
{
|
||||
return ReadInt64(reader);
|
||||
return ReadInt64 (reader);
|
||||
}
|
||||
case 0x05:
|
||||
{
|
||||
return ReadInt64(reader);
|
||||
return ReadInt64 (reader);
|
||||
}
|
||||
case 0x81:
|
||||
{
|
||||
return ReadArray(reader);
|
||||
return ReadArray (reader);
|
||||
}
|
||||
case 0xC1:
|
||||
{
|
||||
return ReadDictionary(reader);
|
||||
return ReadDictionary (reader);
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new Exception("unknown object type");
|
||||
throw new Exception ("unknown object type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static object ReadByteArray(BinaryReader reader)
|
||||
static object ReadByteArray (BinaryReader reader)
|
||||
{
|
||||
var count = ReadInt32(reader);
|
||||
var array = reader.ReadBytes(count);
|
||||
var count = ReadInt32 (reader);
|
||||
var array = reader.ReadBytes (count);
|
||||
return array;
|
||||
}
|
||||
|
||||
static object ReadArray(BinaryReader reader)
|
||||
static object ReadArray (BinaryReader reader)
|
||||
{
|
||||
var count = ReadInt32(reader);
|
||||
var count = ReadInt32 (reader);
|
||||
|
||||
var array = new List<object>(count);
|
||||
var array = new List<object> (count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var obj = ReadObject(reader);
|
||||
array.Add(obj);
|
||||
var obj = ReadObject (reader);
|
||||
array.Add (obj);
|
||||
}
|
||||
|
||||
return array.ToArray();
|
||||
return array.ToArray ();
|
||||
}
|
||||
|
||||
static object ReadDictionary(BinaryReader reader)
|
||||
static object ReadDictionary (BinaryReader reader)
|
||||
{
|
||||
var count = ReadInt32(reader);
|
||||
var count = ReadInt32 (reader);
|
||||
|
||||
var dictionary = new Dictionary<string, object>(count);
|
||||
var dictionary = new Dictionary<string, object> (count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var name = ReadString(reader);
|
||||
var obj = ReadObject(reader);
|
||||
dictionary.Add(name, obj);
|
||||
var name = ReadString (reader);
|
||||
var obj = ReadObject (reader);
|
||||
dictionary.Add (name, obj);
|
||||
}
|
||||
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
static int ReadInt32(BinaryReader reader)
|
||||
static int ReadInt32 (BinaryReader reader)
|
||||
{
|
||||
return Binary.BigEndian(reader.ReadInt32());
|
||||
return Binary.BigEndian (reader.ReadInt32 ());
|
||||
}
|
||||
|
||||
static long ReadInt64(BinaryReader reader)
|
||||
static long ReadInt64 (BinaryReader reader)
|
||||
{
|
||||
return Binary.BigEndian(reader.ReadInt64());
|
||||
return Binary.BigEndian (reader.ReadInt64 ());
|
||||
}
|
||||
|
||||
static string ReadString(BinaryReader reader)
|
||||
static string ReadString (BinaryReader reader)
|
||||
{
|
||||
var length = ReadInt32(reader);
|
||||
var buffer = reader.ReadBytes(sizeof(short) * length);
|
||||
return Encoding.Unicode.GetString(buffer);
|
||||
var length = ReadInt32 (reader);
|
||||
var buffer = reader.ReadBytes (sizeof(short) * length);
|
||||
return Encoding.Unicode.GetString (buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,16 +8,18 @@
|
||||
// C# port by morkt
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Windows.Media;
|
||||
using GameRes.Formats.QoiCodec;
|
||||
using GameRes.Utility;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using K4os.Compression.LZ4;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace GameRes.Formats.KiriKiri
|
||||
{
|
||||
@@ -1150,8 +1152,8 @@ namespace GameRes.Formats.KiriKiri
|
||||
{
|
||||
if (m_input.Position == m_input.Length)
|
||||
return false;
|
||||
var v1 = m_input.ReadUInt16 ();
|
||||
var v2 = m_input.ReadUInt16 ();
|
||||
var v1 = m_input.ReadInt32 ();
|
||||
var v2 = (int)((uint)v1 >> 16);
|
||||
var input = m_input.ReadBytes (v2);
|
||||
if (v2 != input.Length)
|
||||
throw new EndOfStreamException ();
|
||||
@@ -1177,6 +1179,7 @@ namespace GameRes.Formats.KiriKiri
|
||||
return true;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int ReadByte ()
|
||||
{
|
||||
if (m_pos == m_size[m_index])
|
||||
@@ -1218,95 +1221,6 @@ namespace GameRes.Formats.KiriKiri
|
||||
}
|
||||
}
|
||||
|
||||
static class QoiCodec
|
||||
{
|
||||
public const int Index = 0x00;
|
||||
public const int Diff = 0x40;
|
||||
public const int Luma = 0x80;
|
||||
public const int Run = 0xC0;
|
||||
public const int Rgb = 0xFE;
|
||||
public const int Rgba = 0xFF;
|
||||
public const int Mask2 = 0xC0;
|
||||
public const int HashTableSize = 64;
|
||||
}
|
||||
|
||||
class QoiDecodeStream
|
||||
{
|
||||
readonly IBinaryStream m_input;
|
||||
readonly byte[] m_table;
|
||||
uint m_pixel;
|
||||
|
||||
public QoiDecodeStream (IBinaryStream input)
|
||||
{
|
||||
m_input = input;
|
||||
m_table = new byte [4*QoiCodec.HashTableSize];
|
||||
m_pixel = 0xFF000000;
|
||||
}
|
||||
|
||||
public int Read (out uint output)
|
||||
{
|
||||
var r = (byte)m_pixel;
|
||||
var g = (byte)(m_pixel >> 8);
|
||||
var b = (byte)(m_pixel >> 16);
|
||||
var a = (byte)(m_pixel >> 24);
|
||||
var run = 1;
|
||||
var b1 = m_input.ReadByte ();
|
||||
if (-1 == b1)
|
||||
throw new EndOfStreamException ();
|
||||
if (QoiCodec.Rgb == b1)
|
||||
{
|
||||
var rgb = m_input.ReadInt24 ();
|
||||
r = (byte)rgb;
|
||||
g = (byte)(rgb >> 8);
|
||||
b = (byte)(rgb >> 16);
|
||||
}
|
||||
else if (QoiCodec.Rgba == b1)
|
||||
{
|
||||
var rgba = m_input.ReadInt32 ();
|
||||
r = (byte)rgba;
|
||||
g = (byte)(rgba >> 8);
|
||||
b = (byte)(rgba >> 16);
|
||||
a = (byte)(rgba >> 24);
|
||||
}
|
||||
else if (QoiCodec.Index == (b1 & QoiCodec.Mask2))
|
||||
{
|
||||
var p1 = (b1 & ~QoiCodec.Mask2) * 4;
|
||||
r = m_table[p1 ];
|
||||
g = m_table[p1+1];
|
||||
b = m_table[p1+2];
|
||||
a = m_table[p1+3];
|
||||
}
|
||||
else if (QoiCodec.Diff == (b1 & QoiCodec.Mask2))
|
||||
{
|
||||
r += (byte)(((b1 >> 4) & 0x03) - 2);
|
||||
g += (byte)(((b1 >> 2) & 0x03) - 2);
|
||||
b += (byte)((b1 & 0x03) - 2);
|
||||
}
|
||||
else if (QoiCodec.Luma == (b1 & QoiCodec.Mask2))
|
||||
{
|
||||
var b2 = m_input.ReadByte ();
|
||||
if (-1 == b2)
|
||||
throw new EndOfStreamException ();
|
||||
var vg = (b1 & 0x3F) - 32;
|
||||
r += (byte)(vg - 8 + ((b2 >> 4) & 0x0F));
|
||||
g += (byte)vg;
|
||||
b += (byte)(vg - 8 + (b2 & 0x0F));
|
||||
}
|
||||
else if (QoiCodec.Run == (b1 & QoiCodec.Mask2))
|
||||
{
|
||||
run = (b1 & 0x3F) + 1;
|
||||
}
|
||||
var p2 = (r*3 + g*5 + b*7 + a*11) % QoiCodec.HashTableSize*4;
|
||||
m_table[p2 ] = r;
|
||||
m_table[p2+1] = g;
|
||||
m_table[p2+2] = b;
|
||||
m_table[p2+3] = a;
|
||||
m_pixel = (uint)(r | (g << 8) | (b << 16) | (a << 24));
|
||||
output = (uint)(b | (g << 8) | (r << 16) | (a << 24));
|
||||
return run;
|
||||
}
|
||||
}
|
||||
|
||||
class QoiBlockDecoder
|
||||
{
|
||||
readonly QoiDecodeStream m_qoi;
|
||||
@@ -1433,9 +1347,9 @@ namespace GameRes.Formats.KiriKiri
|
||||
|
||||
for (var i = 0; i < block_count; i++)
|
||||
{
|
||||
var qoi_size = (int) dtbl[1+2*i];
|
||||
var run_size = (int) rtbl[1+i];
|
||||
var num_pixels = (int) dtbl[1+2*i+1];
|
||||
var qoi_size = (int) dtbl[1+2*i ];
|
||||
var run_size = (int) rtbl[1+i];
|
||||
|
||||
src.Position = qoi_offset;
|
||||
var qoi = src.ReadBytes (qoi_size);
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace GameRes.Formats.NeXAS
|
||||
Settings = new[] { PacEncoding };
|
||||
}
|
||||
|
||||
EncodingSetting PacEncoding = new EncodingSetting ("NexasEncodingCP", "DefaultEncoding");
|
||||
readonly EncodingSetting PacEncoding = new EncodingSetting ("NexasEncodingCP", "DefaultEncoding");
|
||||
|
||||
public override ArcFile TryOpen (ArcView file)
|
||||
{
|
||||
@@ -89,17 +89,17 @@ namespace GameRes.Formats.NeXAS
|
||||
return null;
|
||||
|
||||
List<Entry> dir = null;
|
||||
INexasIndexReader reader = new IndexReader (file, PacEncoding.Get<Encoding>());
|
||||
INexasIndexReader reader = new IndexReaderV1 (file, PacEncoding.Get<Encoding> ());
|
||||
try
|
||||
{
|
||||
dir = reader.Read();
|
||||
dir = reader.Read ();
|
||||
}
|
||||
catch {}
|
||||
|
||||
if (null == dir)
|
||||
{
|
||||
reader = new OldIndexReader (file);
|
||||
dir = reader.Read();
|
||||
reader = new IndexReaderV0 (file);
|
||||
dir = reader.Read ();
|
||||
|
||||
if (null == dir)
|
||||
return null;
|
||||
@@ -110,18 +110,18 @@ namespace GameRes.Formats.NeXAS
|
||||
return new PacArchive (file, this, dir, reader.PackType);
|
||||
}
|
||||
|
||||
internal sealed class IndexReader : INexasIndexReader
|
||||
internal sealed class IndexReaderV1 : INexasIndexReader
|
||||
{
|
||||
ArcView m_file;
|
||||
int m_count;
|
||||
int m_pack_type;
|
||||
Encoding m_encoding;
|
||||
readonly ArcView m_file;
|
||||
readonly int m_count;
|
||||
readonly int m_pack_type;
|
||||
readonly Encoding m_encoding;
|
||||
|
||||
const int MaxNameLength = 0x40;
|
||||
|
||||
public Compression PackType { get { return (Compression)m_pack_type; } }
|
||||
|
||||
public IndexReader (ArcView file, Encoding enc)
|
||||
public IndexReaderV1 (ArcView file, Encoding enc)
|
||||
{
|
||||
m_file = file;
|
||||
m_count = file.View.ReadInt32 (4);
|
||||
@@ -139,15 +139,15 @@ namespace GameRes.Formats.NeXAS
|
||||
bool success = false;
|
||||
try
|
||||
{
|
||||
success = ReadOld();
|
||||
success = ReadV0 ();
|
||||
}
|
||||
catch { /* ignore parse errors */ }
|
||||
if (!success && !ReadNew())
|
||||
if (!success && !ReadV1 ())
|
||||
return null;
|
||||
return m_dir;
|
||||
}
|
||||
|
||||
bool ReadNew ()
|
||||
bool ReadV1 ()
|
||||
{
|
||||
uint index_size = m_file.View.ReadUInt32 (m_file.MaxOffset-4);
|
||||
int unpacked_size = m_count*0x4C;
|
||||
@@ -163,9 +163,9 @@ namespace GameRes.Formats.NeXAS
|
||||
return ReadFromStream (input, 0x40);
|
||||
}
|
||||
|
||||
bool ReadOld ()
|
||||
bool ReadV0 ()
|
||||
{
|
||||
using (var input = m_file.CreateStream())
|
||||
using (var input = m_file.CreateStream ())
|
||||
{
|
||||
input.Position = 0xC;
|
||||
if (ReadFromStream (input, 0x20))
|
||||
@@ -177,16 +177,16 @@ namespace GameRes.Formats.NeXAS
|
||||
|
||||
bool ReadFromStream (IBinaryStream index, int name_length)
|
||||
{
|
||||
m_dir.Clear();
|
||||
m_dir.Clear ();
|
||||
for (int i = 0; i < m_count; ++i)
|
||||
{
|
||||
var name = index.ReadCString (name_length, m_encoding);
|
||||
if (string.IsNullOrWhiteSpace (name))
|
||||
return false;
|
||||
var entry = FormatCatalog.Instance.Create<PackedEntry> (name);
|
||||
entry.Offset = index.ReadUInt32();
|
||||
entry.UnpackedSize = index.ReadUInt32();
|
||||
entry.Size = index.ReadUInt32();
|
||||
entry.Offset = index.ReadUInt32 ();
|
||||
entry.UnpackedSize = index.ReadUInt32 ();
|
||||
entry.Size = index.ReadUInt32 ();
|
||||
if (!entry.CheckPlacement (m_file.MaxOffset))
|
||||
return false;
|
||||
switch (m_pack_type)
|
||||
@@ -212,14 +212,14 @@ namespace GameRes.Formats.NeXAS
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class OldIndexReader : INexasIndexReader
|
||||
internal sealed class IndexReaderV0 : INexasIndexReader
|
||||
{
|
||||
ArcView m_file;
|
||||
uint m_header_size;
|
||||
readonly ArcView m_file;
|
||||
readonly uint m_header_size;
|
||||
|
||||
public Compression PackType { get { return Compression.NeedDecryptionOnly; } }
|
||||
|
||||
public OldIndexReader (ArcView file)
|
||||
public IndexReaderV0 (ArcView file)
|
||||
{
|
||||
m_file = file;
|
||||
m_header_size = file.View.ReadUInt32 (3);
|
||||
@@ -230,25 +230,25 @@ namespace GameRes.Formats.NeXAS
|
||||
public List<Entry> Read ()
|
||||
{
|
||||
m_dir = new List<Entry> ();
|
||||
using (var input = m_file.CreateStream())
|
||||
using (var input = m_file.CreateStream ())
|
||||
{
|
||||
input.Position = 7;
|
||||
while (input.Position < m_header_size)
|
||||
{
|
||||
byte c;
|
||||
List<byte> name_buffer = new List<byte>();
|
||||
List<byte> name_buffer = new List<byte> ();
|
||||
while (true)
|
||||
{
|
||||
c = (byte)input.ReadByte();
|
||||
c = (byte)input.ReadByte ();
|
||||
if (c == 0) break;
|
||||
name_buffer.Add ((byte)~c);
|
||||
}
|
||||
var name = Binary.GetCString (name_buffer.ToArray(), 0);
|
||||
var name = Binary.GetCString (name_buffer.ToArray (), 0);
|
||||
if (string.IsNullOrWhiteSpace (name))
|
||||
return null;
|
||||
var entry = FormatCatalog.Instance.Create<Entry> (name);
|
||||
entry.Offset = input.ReadUInt32() + m_header_size;
|
||||
entry.Size = input.ReadUInt32();
|
||||
entry.Offset = input.ReadUInt32 () + m_header_size;
|
||||
entry.Size = input.ReadUInt32 ();
|
||||
if (!entry.CheckPlacement (m_file.MaxOffset))
|
||||
return null;
|
||||
m_dir.Add (entry);
|
||||
@@ -268,11 +268,14 @@ namespace GameRes.Formats.NeXAS
|
||||
return input;
|
||||
if (Compression.NeedDecryptionOnly == pac.PackType)
|
||||
{
|
||||
var data = new byte[entry.Size];
|
||||
input.Read (data, 0, data.Length);
|
||||
for (int i = 0; i < Math.Min (3, data.Length); i++)
|
||||
data[i] = (byte)~data[i];
|
||||
return new BinMemoryStream (data, entry.Name);
|
||||
using (input)
|
||||
{
|
||||
var data = new byte[entry.Size];
|
||||
input.Read (data, 0, data.Length);
|
||||
for (int i = 0; i < Math.Min (3, data.Length); i++)
|
||||
data[i] = (byte)~data[i];
|
||||
return new BinMemoryStream (data, entry.Name);
|
||||
}
|
||||
}
|
||||
if (null == pent || !pent.IsPacked)
|
||||
return input;
|
||||
@@ -296,8 +299,11 @@ namespace GameRes.Formats.NeXAS
|
||||
case Compression.Zstd:
|
||||
case Compression.ZstdOrNone:
|
||||
{
|
||||
var unpacked = ZstdDecompress (input, pent.UnpackedSize);
|
||||
return new BinMemoryStream (unpacked, entry.Name);
|
||||
using (input)
|
||||
{
|
||||
var unpacked = ZstdDecompress (input, pent.UnpackedSize);
|
||||
return new BinMemoryStream (unpacked, entry.Name);
|
||||
}
|
||||
}
|
||||
default:
|
||||
return input;
|
||||
@@ -308,7 +314,7 @@ namespace GameRes.Formats.NeXAS
|
||||
{
|
||||
var dst = new byte[unpacked_size];
|
||||
var decoder = new HuffmanDecoder (packed, dst);
|
||||
return decoder.Unpack();
|
||||
return decoder.Unpack ();
|
||||
}
|
||||
|
||||
static private byte[] ZstdDecompress (Stream s, uint unpackedSize)
|
||||
@@ -316,7 +322,16 @@ namespace GameRes.Formats.NeXAS
|
||||
using (var ds = new ZstdSharp.DecompressionStream (s))
|
||||
{
|
||||
var dst = new byte[unpackedSize];
|
||||
ds.Read (dst, 0, dst.Length);
|
||||
int decompressedSize = 0;
|
||||
|
||||
while (decompressedSize < unpackedSize)
|
||||
{
|
||||
var count = ds.Read (dst, decompressedSize, (int)unpackedSize-decompressedSize);
|
||||
if (0 == count)
|
||||
return dst;
|
||||
decompressedSize += count;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace GameRes.Formats.NeXAS
|
||||
switch (info.BPP)
|
||||
{
|
||||
case 8: Format = PixelFormats.Indexed8; break;
|
||||
case 16: Format = PixelFormats.Bgr555; break;
|
||||
case 16: Format = info.Version == 2 ? PixelFormats.Bgr565 : PixelFormats.Bgr555; break;
|
||||
case 24: Format = PixelFormats.Bgr24; break;
|
||||
case 32: Format = PixelFormats.Bgr32; break;
|
||||
default: throw new NotSupportedException ("Not supported GRP image color depth");
|
||||
|
||||
118
ArcFormats/QoiCodec.cs
Normal file
118
ArcFormats/QoiCodec.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
//! \file QoiCodec.cs
|
||||
//! \date Sun Apr 12 2026
|
||||
//! \brief Quite OK Image Format
|
||||
//
|
||||
// Copyright (C) 2016 by morkt
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace GameRes.Formats.QoiCodec
|
||||
{
|
||||
static class QoiConst
|
||||
{
|
||||
public const int Index = 0x00;
|
||||
public const int Diff = 0x40;
|
||||
public const int Luma = 0x80;
|
||||
public const int Run = 0xC0;
|
||||
public const int Rgb = 0xFE;
|
||||
public const int Rgba = 0xFF;
|
||||
public const int Mask2 = 0xC0;
|
||||
public const int HashTableSize = 64;
|
||||
}
|
||||
|
||||
public class QoiDecodeStream
|
||||
{
|
||||
readonly IBinaryStream m_input;
|
||||
readonly byte[] m_table;
|
||||
uint m_pixel;
|
||||
|
||||
public QoiDecodeStream (IBinaryStream input)
|
||||
{
|
||||
m_input = input;
|
||||
m_table = new byte [4*QoiConst.HashTableSize];
|
||||
m_pixel = 0xFF000000;
|
||||
}
|
||||
|
||||
public int Read (out uint output)
|
||||
{
|
||||
var r = (byte)m_pixel;
|
||||
var g = (byte)(m_pixel >> 8);
|
||||
var b = (byte)(m_pixel >> 16);
|
||||
var a = (byte)(m_pixel >> 24);
|
||||
var run = 1;
|
||||
var b1 = m_input.ReadByte ();
|
||||
if (-1 == b1)
|
||||
throw new EndOfStreamException ();
|
||||
if (QoiConst.Rgb == b1)
|
||||
{
|
||||
var rgb = m_input.ReadInt24 ();
|
||||
r = (byte)rgb;
|
||||
g = (byte)(rgb >> 8);
|
||||
b = (byte)(rgb >> 16);
|
||||
}
|
||||
else if (QoiConst.Rgba == b1)
|
||||
{
|
||||
var rgba = m_input.ReadInt32 ();
|
||||
r = (byte)rgba;
|
||||
g = (byte)(rgba >> 8);
|
||||
b = (byte)(rgba >> 16);
|
||||
a = (byte)(rgba >> 24);
|
||||
}
|
||||
else if (QoiConst.Index == (b1 & QoiConst.Mask2))
|
||||
{
|
||||
var p1 = (b1 & ~QoiConst.Mask2) * 4;
|
||||
r = m_table[p1 ];
|
||||
g = m_table[p1+1];
|
||||
b = m_table[p1+2];
|
||||
a = m_table[p1+3];
|
||||
}
|
||||
else if (QoiConst.Diff == (b1 & QoiConst.Mask2))
|
||||
{
|
||||
r += (byte)(((b1 >> 4) & 0x03) - 2);
|
||||
g += (byte)(((b1 >> 2) & 0x03) - 2);
|
||||
b += (byte)((b1 & 0x03) - 2);
|
||||
}
|
||||
else if (QoiConst.Luma == (b1 & QoiConst.Mask2))
|
||||
{
|
||||
var b2 = m_input.ReadByte ();
|
||||
if (-1 == b2)
|
||||
throw new EndOfStreamException ();
|
||||
var vg = (b1 & 0x3F) - 32;
|
||||
r += (byte)(vg - 8 + ((b2 >> 4) & 0x0F));
|
||||
g += (byte)vg;
|
||||
b += (byte)(vg - 8 + (b2 & 0x0F));
|
||||
}
|
||||
else if (QoiConst.Run == (b1 & QoiConst.Mask2))
|
||||
{
|
||||
run = (b1 & 0x3F) + 1;
|
||||
}
|
||||
var p2 = (r*3 + g*5 + b*7 + a*11) % QoiConst.HashTableSize*4;
|
||||
m_table[p2 ] = r;
|
||||
m_table[p2+1] = g;
|
||||
m_table[p2+2] = b;
|
||||
m_table[p2+3] = a;
|
||||
m_pixel = (uint)(r | (g << 8) | (b << 16) | (a << 24));
|
||||
output = (uint)(b | (g << 8) | (r << 16) | (a << 24));
|
||||
return run;
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
64
ArcFormats/WebPCodec.cs
Normal file
64
ArcFormats/WebPCodec.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
//! \file WebPCodec.cs
|
||||
//! \date Sun Apr 12 2026
|
||||
//! \brief Google WebP image format.
|
||||
//
|
||||
// Copyright (C) 2016 by morkt
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace GameRes.Formats
|
||||
{
|
||||
public class WebPCodec
|
||||
{
|
||||
[DllImport("libwebp.dll", EntryPoint = "WebPGetInfo", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int WebPGetInfo ([MarshalAs(UnmanagedType.LPArray)] byte[] data, UIntPtr data_size, ref int width, ref int height);
|
||||
|
||||
[DllImport("libwebp.dll", EntryPoint = "WebPDecodeBGRAInto", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr WebPDecodeBGRAInto ([MarshalAs(UnmanagedType.LPArray)] byte[] data, UIntPtr data_size, IntPtr output_buffer, UIntPtr output_buffer_size, int output_stride);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
|
||||
static extern IntPtr LoadLibraryEx (string lpFileName, IntPtr hReservedNull, uint dwFlags);
|
||||
|
||||
static bool loaded = false;
|
||||
|
||||
const uint LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100;
|
||||
const uint LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800;
|
||||
|
||||
public static void Load ()
|
||||
{
|
||||
if (loaded)
|
||||
return;
|
||||
var dir = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location);
|
||||
dir = Path.Combine (dir, (IntPtr.Size == 4) ? "x86" : "x64");
|
||||
var path = Path.Combine (dir, "libwebp.dll");
|
||||
path = Path.GetFullPath (path);
|
||||
var lib = LoadLibraryEx (path, IntPtr.Zero, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (IntPtr.Zero == lib)
|
||||
throw new Win32Exception (Marshal.GetLastWin32Error ());
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
237
ArcFormats/YuRis/ImageYDG.cs
Normal file
237
ArcFormats/YuRis/ImageYDG.cs
Normal file
@@ -0,0 +1,237 @@
|
||||
//! \file ImageYDG.cs
|
||||
//! \date Sun Apr 12 15:08:10 2026
|
||||
//! \brief YU-RIS compressed image.
|
||||
//
|
||||
// Copyright (C) 2026 by morkt
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using GameRes.Formats.QoiCodec;
|
||||
using GameRes.Utility;
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace GameRes.Formats.YuRis
|
||||
{
|
||||
internal class YdgMetaData : ImageMetaData
|
||||
{
|
||||
public int HeaderLength;
|
||||
}
|
||||
|
||||
internal class YdgSlice
|
||||
{
|
||||
public uint Offset;
|
||||
public uint Size;
|
||||
public byte[] Data;
|
||||
public int X;
|
||||
public int Y;
|
||||
public int Height;
|
||||
}
|
||||
|
||||
[Export(typeof(ImageFormat))]
|
||||
public class YdgFormat : ImageFormat
|
||||
{
|
||||
public override string Tag { get { return "YDG"; } }
|
||||
public override string Description { get { return "YU-RIS compressed image format"; } }
|
||||
public override uint Signature { get { return 0x00474459; } } // 'YDG\0'
|
||||
|
||||
public YdgFormat ()
|
||||
{
|
||||
Extensions = new string[] { "ydg" };
|
||||
}
|
||||
|
||||
public override ImageMetaData ReadMetaData (IBinaryStream stream)
|
||||
{
|
||||
var header = stream.ReadHeader (0x30);
|
||||
if (!header.AsciiEqual ("YDG\0"))
|
||||
return null;
|
||||
if (!header.AsciiEqual (4, "YU-RIS"))
|
||||
return null;
|
||||
return new YdgMetaData
|
||||
{
|
||||
Width = header.ToUInt16 (0x20),
|
||||
Height = header.ToUInt16 (0x22),
|
||||
BPP = 32,
|
||||
HeaderLength = header.ToInt32 (0x10),
|
||||
};
|
||||
}
|
||||
|
||||
public override ImageData Read (IBinaryStream stream, ImageMetaData info)
|
||||
{
|
||||
var meta = (YdgMetaData) info;
|
||||
var reader = new YdgReader (stream, meta);
|
||||
reader.Unpack ();
|
||||
return ImageData.Create (meta, reader.Format, null, reader.Data);
|
||||
}
|
||||
|
||||
public override void Write (Stream file, ImageData image)
|
||||
{
|
||||
throw new NotImplementedException ("YdgFormat.Write not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class YdgReader
|
||||
{
|
||||
readonly IBinaryStream m_input;
|
||||
readonly YdgMetaData m_info;
|
||||
readonly byte[] m_output;
|
||||
|
||||
public PixelFormat Format { get; private set; }
|
||||
public byte[] Data { get { return m_output; } }
|
||||
|
||||
public YdgReader (IBinaryStream input, YdgMetaData info)
|
||||
{
|
||||
m_input = input;
|
||||
m_info = info;
|
||||
m_output = new byte[4*(int)info.Width*(int)info.Height];
|
||||
Format = PixelFormats.Bgra32;
|
||||
}
|
||||
|
||||
public void Unpack ()
|
||||
{
|
||||
var slices = ReadSlices ();
|
||||
var options = new ParallelOptions { MaxDegreeOfParallelism = 4 };
|
||||
Parallel.ForEach (slices, options, slice =>
|
||||
{
|
||||
var pixels = DecodeSlice (slice.Data, out int slice_width, out int slice_height);
|
||||
if (slice_height > slice.Height)
|
||||
throw new InvalidFormatException ();
|
||||
var height = Math.Min (slice_height, slice.Height);
|
||||
CopySlice (pixels, slice_width, height, slice.X, slice.Y);
|
||||
});
|
||||
}
|
||||
|
||||
YdgSlice[] ReadSlices ()
|
||||
{
|
||||
m_input.Position = m_info.HeaderLength;
|
||||
var count = m_input.ReadInt32 ();
|
||||
if (count <= 0)
|
||||
throw new InvalidFormatException ();
|
||||
var slices = new YdgSlice[count];
|
||||
var y = 0;
|
||||
for (var i = 0; i < slices.Length; i++)
|
||||
{
|
||||
var slice = new YdgSlice
|
||||
{
|
||||
Offset = m_input.ReadUInt32 (),
|
||||
Size = m_input.ReadUInt32 (),
|
||||
X = m_input.ReadUInt16 (),
|
||||
Y = y,
|
||||
Height = m_input.ReadUInt16 (),
|
||||
};
|
||||
y += slice.Height;
|
||||
m_input.ReadUInt32 ();
|
||||
slices[i] = slice;
|
||||
}
|
||||
foreach (var slice in slices)
|
||||
{
|
||||
m_input.Position = slice.Offset;
|
||||
slice.Data = m_input.ReadBytes ((int)slice.Size);
|
||||
}
|
||||
return slices;
|
||||
}
|
||||
|
||||
byte[] DecodeSlice (byte[] data, out int width, out int height)
|
||||
{
|
||||
if (Binary.AsciiEqual (data, 0, "RIFF") && Binary.AsciiEqual (data, 8, "WEBP"))
|
||||
return DecodeWebP (data, out width, out height);
|
||||
return DecodeQoi (data, out width, out height);
|
||||
}
|
||||
|
||||
void CopySlice (byte[] pixels, int src_width, int src_height, int dst_x, int dst_y)
|
||||
{
|
||||
var copy_width = Math.Min (src_width, (int)m_info.Width-dst_x);
|
||||
var copy_height = Math.Min (src_height, (int)m_info.Height-dst_y);
|
||||
if (copy_width <= 0 || copy_height <= 0)
|
||||
return;
|
||||
var src_stride = 4*src_width;
|
||||
var dst_stride = 4*(int)m_info.Width;
|
||||
var dst = dst_y*dst_stride + 4*dst_x;
|
||||
var row_bytes = 4*copy_width;
|
||||
var src = 0;
|
||||
for (var y = 0; y < copy_height; y++)
|
||||
{
|
||||
Buffer.BlockCopy (pixels, src, m_output, dst, row_bytes);
|
||||
src += src_stride;
|
||||
dst += dst_stride;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] DecodeWebP (byte[] data, out int width, out int height)
|
||||
{
|
||||
width = 0;
|
||||
height = 0;
|
||||
WebPCodec.Load ();
|
||||
if (1 != WebPCodec.WebPGetInfo (data, (UIntPtr)data.Length, ref width, ref height))
|
||||
throw new InvalidFormatException ("WebP image decoder failed.");
|
||||
var stride = 4*width;
|
||||
var output = new byte[stride*height];
|
||||
var handle = GCHandle.Alloc (output, GCHandleType.Pinned);
|
||||
try
|
||||
{
|
||||
if (IntPtr.Zero == WebPCodec.WebPDecodeBGRAInto (data, (UIntPtr)data.Length, handle.AddrOfPinnedObject (), (UIntPtr)output.Length, stride))
|
||||
throw new InvalidFormatException ("WebP image decoder failed.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
handle.Free ();
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
byte[] DecodeQoi (byte[] data, out int width, out int height)
|
||||
{
|
||||
using (var input = new BinMemoryStream (data))
|
||||
{
|
||||
if (0x66696F71 != input.ReadInt32 ()) // "qoif"
|
||||
throw new InvalidFormatException ("Invalid QOI signature");
|
||||
width = (int)Binary.BigEndian (input.ReadUInt32 ());
|
||||
height = (int)Binary.BigEndian (input.ReadUInt32 ());
|
||||
var channels = input.ReadByte ();
|
||||
var colorspace = input.ReadByte ();
|
||||
var count = 4*width*height;
|
||||
var output = new byte[count];
|
||||
var qoi = new QoiDecodeStream (input);
|
||||
uint pixel = 0;
|
||||
var run = 0;
|
||||
var dst = 0;
|
||||
while (dst < count)
|
||||
{
|
||||
if (run > 1)
|
||||
--run;
|
||||
else
|
||||
{
|
||||
run = qoi.Read (out pixel);
|
||||
}
|
||||
output[dst ] = (byte)pixel;
|
||||
output[dst+1] = (byte)(pixel >> 8);
|
||||
output[dst+2] = (byte)(pixel >> 16);
|
||||
output[dst+3] = (byte)(pixel >> 24);
|
||||
dst += 4;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using GameRes.Utility;
|
||||
|
||||
namespace GameRes
|
||||
@@ -142,6 +143,74 @@ namespace GameRes
|
||||
}
|
||||
|
||||
public static class ByteArrayExt
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ushort ToUInt16 (this byte[] arr, int index)
|
||||
{
|
||||
return (ushort)(arr[index] | arr[index+1] << 8);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static short ToInt16 (this byte[] arr, int index)
|
||||
{
|
||||
return (short)(arr[index] | arr[index+1] << 8);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int ToInt24 (this byte[] arr, int index)
|
||||
{
|
||||
return arr[index] | arr[index+1] << 8 | arr[index+2] << 16;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint ToUInt32 (this byte[] arr, int index)
|
||||
{
|
||||
return (uint)(arr[index] | arr[index+1] << 8 | arr[index+2] << 16 | arr[index+3] << 24);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int ToInt32 (this byte[] arr, int index)
|
||||
{
|
||||
return (int)ToUInt32 (arr, index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong ToUInt64 (this byte[] arr, int index)
|
||||
{
|
||||
return (ulong)ToUInt32 (arr, index) | ((ulong)ToUInt32 (arr, index+4) << 32);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long ToInt64 (this byte[] arr, int index)
|
||||
{
|
||||
return (long)ToUInt64 (arr, index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool AsciiEqual (this byte[] arr, int index, string str)
|
||||
{
|
||||
if (arr.Length-index < str.Length)
|
||||
return false;
|
||||
for (int i = 0; i < str.Length; ++i)
|
||||
if ((char)arr[index+i] != str[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool AsciiEqual (this byte[] arr, string str)
|
||||
{
|
||||
return arr.AsciiEqual (0, str);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static string GetCString (this byte[] arr, int index, int length_limit)
|
||||
{
|
||||
return Binary.GetCString (arr, index, length_limit);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CowArrayExt
|
||||
{
|
||||
public static ushort ToUInt16<TArray> (this TArray arr, int index) where TArray : IList<byte>
|
||||
{
|
||||
|
||||
@@ -364,7 +364,7 @@ namespace GameRes
|
||||
{
|
||||
var scheme = format.Scheme;
|
||||
if (null != scheme)
|
||||
db.SchemeMap[format.Tag] = scheme;
|
||||
db.SchemeMap.Add (format.Tag, scheme);
|
||||
}
|
||||
SerializeScheme (output, db);
|
||||
}
|
||||
|
||||
@@ -75,9 +75,22 @@
|
||||
</Reference>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.5.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.6.1\lib\net462\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel.Composition" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.Memory, Version=4.0.5.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.6.3\lib\net462\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.6.1\lib\net462\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.6.1.2\lib\net462\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.AccessControl, Version=6.0.0.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.AccessControl.6.0.1\lib\net461\System.Security.AccessControl.dll</HintPath>
|
||||
</Reference>
|
||||
|
||||
@@ -24,33 +24,45 @@
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace GameRes.Utility
|
||||
{
|
||||
public static class Binary
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint BigEndian (uint u)
|
||||
{
|
||||
return u << 24 | (u & 0xff00) << 8 | (u & 0xff0000) >> 8 | u >> 24;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int BigEndian (int i)
|
||||
{
|
||||
return (int)BigEndian ((uint)i);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ushort BigEndian (ushort u)
|
||||
{
|
||||
return (ushort)(u << 8 | u >> 8);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static short BigEndian (short i)
|
||||
{
|
||||
return (short)BigEndian ((ushort)i);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong BigEndian (ulong u)
|
||||
{
|
||||
return (ulong)BigEndian((uint)(u & 0xffffffff)) << 32
|
||||
| (ulong)BigEndian((uint)(u >> 32));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long BigEndian (long i)
|
||||
{
|
||||
return (long)BigEndian ((ulong)i);
|
||||
@@ -123,36 +135,42 @@ namespace GameRes.Utility
|
||||
return GetCString (data, index, data.Length - index, Encodings.cp932);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint RotR (uint v, int count)
|
||||
{
|
||||
count &= 0x1F;
|
||||
return v >> count | v << (32-count);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint RotL (uint v, int count)
|
||||
{
|
||||
count &= 0x1F;
|
||||
return v << count | v >> (32-count);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong RotR (ulong v, int count)
|
||||
{
|
||||
count &= 0x3F;
|
||||
return v >> count | v << (64-count);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong RotL (ulong v, int count)
|
||||
{
|
||||
count &= 0x3F;
|
||||
return v << count | v >> (64-count);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte RotByteR (byte v, int count)
|
||||
{
|
||||
count &= 7;
|
||||
return (byte)(v >> count | v << (8-count));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte RotByteL (byte v, int count)
|
||||
{
|
||||
count &= 7;
|
||||
@@ -162,32 +180,62 @@ namespace GameRes.Utility
|
||||
|
||||
public static class BigEndian
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ushort ToUInt16<TArray> (TArray value, int index) where TArray : IList<byte>
|
||||
{
|
||||
return (ushort)(value[index] << 8 | value[index+1]);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static short ToInt16<TArray> (TArray value, int index) where TArray : IList<byte>
|
||||
{
|
||||
return (short)(value[index] << 8 | value[index+1]);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint ToUInt32<TArray> (TArray value, int index) where TArray : IList<byte>
|
||||
{
|
||||
return (uint)(value[index] << 24 | value[index+1] << 16 | value[index+2] << 8 | value[index+3]);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int ToInt32<TArray> (TArray value, int index) where TArray : IList<byte>
|
||||
{
|
||||
return (int)ToUInt32 (value, index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ushort ToUInt16 (byte[] value, int index)
|
||||
{
|
||||
return (ushort)(value[index] << 8 | value[index+1]);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static short ToInt16 (byte[] value, int index)
|
||||
{
|
||||
return (short)(value[index] << 8 | value[index+1]);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint ToUInt32 (byte[] value, int index)
|
||||
{
|
||||
return (uint)(value[index] << 24 | value[index+1] << 16 | value[index+2] << 8 | value[index+3]);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int ToInt32 (byte[] value, int index)
|
||||
{
|
||||
return (int)ToUInt32 (value, index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Pack (ushort value, byte[] buf, int index)
|
||||
{
|
||||
buf[index] = (byte)(value >> 8);
|
||||
buf[index+1] = (byte)(value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Pack (uint value, byte[] buf, int index)
|
||||
{
|
||||
buf[index] = (byte)(value >> 24);
|
||||
@@ -196,22 +244,26 @@ namespace GameRes.Utility
|
||||
buf[index+3] = (byte)(value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Pack (ulong value, byte[] buf, int index)
|
||||
{
|
||||
Pack ((uint)(value >> 32), buf, index);
|
||||
Pack ((uint)value, buf, index+4);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Pack (short value, byte[] buf, int index)
|
||||
{
|
||||
Pack ((ushort)value, buf, index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Pack (int value, byte[] buf, int index)
|
||||
{
|
||||
Pack ((uint)value, buf, index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Pack (long value, byte[] buf, int index)
|
||||
{
|
||||
Pack ((ulong)value, buf, index);
|
||||
@@ -220,42 +272,86 @@ namespace GameRes.Utility
|
||||
|
||||
public static class LittleEndian
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ushort ToUInt16<TArray> (TArray value, int index) where TArray : IList<byte>
|
||||
{
|
||||
return (ushort)(value[index] | value[index+1] << 8);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static short ToInt16<TArray> (TArray value, int index) where TArray : IList<byte>
|
||||
{
|
||||
return (short)(value[index] | value[index+1] << 8);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint ToUInt32<TArray> (TArray value, int index) where TArray : IList<byte>
|
||||
{
|
||||
return (uint)(value[index] | value[index+1] << 8 | value[index+2] << 16 | value[index+3] << 24);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int ToInt32<TArray> (TArray value, int index) where TArray : IList<byte>
|
||||
{
|
||||
return (int)ToUInt32 (value, index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong ToUInt64<TArray> (TArray value, int index) where TArray : IList<byte>
|
||||
{
|
||||
return (ulong)ToUInt32 (value, index) | ((ulong)ToUInt32 (value, index+4) << 32);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long ToInt64<TArray> (TArray value, int index) where TArray : IList<byte>
|
||||
{
|
||||
return (long)ToUInt64 (value, index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ushort ToUInt16 (byte[] value, int index)
|
||||
{
|
||||
return (ushort)(value[index] | value[index+1] << 8);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static short ToInt16 (byte[] value, int index)
|
||||
{
|
||||
return (short)(value[index] | value[index+1] << 8);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint ToUInt32 (byte[] value, int index)
|
||||
{
|
||||
return (uint)(value[index] | value[index+1] << 8 | value[index+2] << 16 | value[index+3] << 24);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int ToInt32 (byte[] value, int index)
|
||||
{
|
||||
return (int)ToUInt32 (value, index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong ToUInt64 (byte[] value, int index)
|
||||
{
|
||||
return (ulong)ToUInt32 (value, index) | ((ulong)ToUInt32 (value, index+4) << 32);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long ToInt64 (byte[] value, int index)
|
||||
{
|
||||
return (long)ToUInt64 (value, index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Pack (ushort value, byte[] buf, int index)
|
||||
{
|
||||
buf[index] = (byte)(value);
|
||||
buf[index+1] = (byte)(value >> 8);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Pack (uint value, byte[] buf, int index)
|
||||
{
|
||||
buf[index] = (byte)(value);
|
||||
@@ -264,22 +360,26 @@ namespace GameRes.Utility
|
||||
buf[index+3] = (byte)(value >> 24);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Pack (ulong value, byte[] buf, int index)
|
||||
{
|
||||
Pack ((uint)value, buf, index);
|
||||
Pack ((uint)(value >> 32), buf, index+4);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Pack (short value, byte[] buf, int index)
|
||||
{
|
||||
Pack ((ushort)value, buf, index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Pack (int value, byte[] buf, int index)
|
||||
{
|
||||
Pack ((uint)value, buf, index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Pack (long value, byte[] buf, int index)
|
||||
{
|
||||
Pack ((ulong)value, buf, index);
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
<package id="NAudio.WinForms" version="2.2.1" targetFramework="net472" />
|
||||
<package id="NAudio.WinMM" version="2.2.1" targetFramework="net472" />
|
||||
<package id="Newtonsoft.Json" version="13.0.4" targetFramework="net472" />
|
||||
<package id="System.Buffers" version="4.6.1" targetFramework="net472" />
|
||||
<package id="System.Memory" version="4.6.3" targetFramework="net472" />
|
||||
<package id="System.Numerics.Vectors" version="4.6.1" targetFramework="net472" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="6.1.2" targetFramework="net472" />
|
||||
<package id="System.Security.AccessControl" version="6.0.1" targetFramework="net472" />
|
||||
<package id="System.Security.Principal.Windows" version="5.0.0" targetFramework="net472" />
|
||||
</packages>
|
||||
@@ -26,7 +26,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\Release\</OutputPath>
|
||||
<DefineConstants>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<BaseAddress>301989888</BaseAddress>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\Release\</OutputPath>
|
||||
<DefineConstants>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
|
||||
Reference in New Issue
Block a user