(Legacy): updated bunch of formats.

This commit is contained in:
morkt 2020-03-30 17:25:15 +04:00
parent 8ad1c652c6
commit 1dfa1482b9
16 changed files with 1130 additions and 25 deletions

View File

@ -0,0 +1,68 @@
//! \file ImageBMP.cs
//! \date 2019 May 29
//! \brief Compressed bitmap format.
//
// Copyright (C) 2019 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.ComponentModel.Composition;
using System.IO;
using GameRes.Compression;
namespace GameRes.Formats.AdvgSys
{
[Export(typeof(ImageFormat))]
public class AdvgFormat : ImageFormat
{
public override string Tag { get { return "BMP/ADVG"; } }
public override string Description { get { return "Compressed bitmap format"; } }
public override uint Signature { get { return 0; } }
public override ImageMetaData ReadMetaData (IBinaryStream file)
{
var header = file.ReadHeader (0xA);
if (!((header[4] & 0xF) == 0xF && header.AsciiEqual (5, "BM")))
return null;
using (var input = OpenBitmapStream (file))
return Bmp.ReadMetaData (input);
}
public override ImageData Read (IBinaryStream file, ImageMetaData info)
{
using (var input = OpenBitmapStream (file, true))
return Bmp.Read (input, info);
}
internal IBinaryStream OpenBitmapStream (IBinaryStream input, bool seekable = false)
{
input.Position = 4;
Stream bmp = new LzssStream (input.AsStream, LzssMode.Decompress, true);
if (seekable)
bmp = new SeekableStream (bmp);
return new BinaryStream (bmp, input.Name);
}
public override void Write (Stream file, ImageData image)
{
throw new System.NotImplementedException ("AdvgFormat.Write not implemented");
}
}
}

72
Legacy/Aos/ArcDAT.cs Normal file
View File

@ -0,0 +1,72 @@
//! \file ArcDAT.cs
//! \date 2019 Jun 06
//! \brief AOS engine resource archive.
//
// Copyright (C) 2019 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.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
// [001124][emu] Luna Season ~150 Bun no 1 no Koibito~
namespace GameRes.Formats.Aos
{
[Export(typeof(ArchiveFormat))]
public class DatOpener : ArchiveFormat
{
public override string Tag { get { return "DAT/PACK"; } }
public override string Description { get { return "AOS engine resource archive"; } }
public override uint Signature { get { return 0; } }
public override bool IsHierarchic { get { return false; } }
public override bool CanWrite { get { return false; } }
public override ArcFile TryOpen (ArcView file)
{
if (!file.Name.HasExtension (".dat"))
return null;
var idx_name = VFS.ChangeFileName (file.Name, "index.idx");
if (!VFS.FileExists (idx_name))
return null;
using (var index = VFS.OpenBinaryStream (idx_name))
{
var dir = new List<Entry>();
while (index.PeekByte() != -1)
{
var name = index.ReadCString (0x34);
if (string.IsNullOrEmpty (name))
break;
var entry = Create<Entry> (name);
entry.Offset = index.ReadUInt32();
entry.Size = index.ReadUInt32();
if (!entry.CheckPlacement (file.MaxOffset))
return null;
dir.Add (entry);
}
if (0 == dir.Count)
return null;
return new ArcFile (file, this, dir);
}
}
}
}

70
Legacy/Artel/ArcPFD.cs Normal file
View File

@ -0,0 +1,70 @@
//! \file ArcPFD.cs
//! \date 2019 May 22
//! \brief ADVG Script Interpreter System resource archive.
//
// Copyright (C) 2019 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.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
// [060127][Artel] Horizont
namespace GameRes.Formats.Artel
{
[Export(typeof(ArchiveFormat))]
public class PfdOpener : ArchiveFormat
{
public override string Tag { get { return "PFD"; } }
public override string Description { get { return "Artel ADVG engine resource archive"; } }
public override uint Signature { get { return 0; } }
public override bool IsHierarchic { get { return false; } }
public override bool CanWrite { get { return false; } }
public override ArcFile TryOpen (ArcView file)
{
int count = file.View.ReadInt32 (0);
if (!IsSaneCount (count))
return null;
int index_offset = 4;
int data_offset = index_offset + count * 0x20;
var dir = new List<Entry> (count);
for (int i = 0; i < count; ++i)
{
var name = file.View.ReadString (index_offset, 0x15);
if (string.IsNullOrEmpty (name))
return null;
var ext = file.View.ReadString (index_offset+0x15, 3);
if (!string.IsNullOrEmpty (ext))
name = Path.ChangeExtension (name, ext);
var entry = Create<Entry> (name);
entry.Offset = file.View.ReadUInt32 (index_offset+0x18);
entry.Size = file.View.ReadUInt32 (index_offset+0x1C);
if (entry.Offset < data_offset || !entry.CheckPlacement (file.MaxOffset))
return null;
dir.Add (entry);
index_offset += 0x20;
}
return new ArcFile (file, this, dir);
}
}
}

60
Legacy/Artel/AudioMUW.cs Normal file
View File

@ -0,0 +1,60 @@
//! \file AudioMUW.cs
//! \date 2019 May 22
//! \brief ADVG Script Interpreter System audio file.
//
// Copyright (C) 2019 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.ComponentModel.Composition;
namespace GameRes.Formats.Artel
{
[Export(typeof(AudioFormat))]
public class MuwAudio : AudioFormat
{
public override string Tag { get { return "MUW"; } }
public override string Description { get { return "Artel ADVG engine audio file"; } }
public override uint Signature { get { return 0x46464952; } } // 'RIFF'
public override bool CanWrite { get { return false; } }
public override SoundInput TryOpen (IBinaryStream file)
{
var header = file.ReadHeader (0x24);
if (!header.AsciiEqual (0, "RIFF") || !header.AsciiEqual (8, "PCMWFMT "))
return null;
uint data_pos = header.ToUInt32 (0x10) + 0x14;
file.Position = data_pos;
if (file.ReadUInt32() != 0x61746164) // 'data'
return null;
uint data_size = file.ReadUInt32();
var format = new WaveFormat {
FormatTag = header.ToUInt16 (0x14),
Channels = header.ToUInt16 (0x16),
SamplesPerSecond = header.ToUInt32 (0x18),
AverageBytesPerSecond = header.ToUInt32 (0x1C),
BlockAlign = header.ToUInt16 (0x20),
BitsPerSample = header.ToUInt16 (0x22),
};
var pcm = new StreamRegion (file.AsStream, data_pos+8, data_size);
return new RawPcmInput (pcm, format);
}
}
}

165
Legacy/Artel/ImageMRL.cs Normal file
View File

@ -0,0 +1,165 @@
//! \file ImageMRL.cs
//! \date 2019 May 22
//! \brief ADVG Script Interpreter System image format.
//
// Copyright (C) 2019 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.ComponentModel.Composition;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace GameRes.Formats.Artel
{
internal class MrlMetaData : ImageMetaData
{
public bool HasAlpha;
}
[Export(typeof(ImageFormat))]
public class MrlFormat : ImageFormat
{
public override string Tag { get { return "MRL"; } }
public override string Description { get { return "Artel ADVG engine image format"; } }
public override uint Signature { get { return 0x524D754D; } } // 'MuMRL'
public override ImageMetaData ReadMetaData (IBinaryStream file)
{
var header = file.ReadHeader (0x18);
if (header[4] != 'L')
return null;
int bpp = header.ToUInt16 (0xC) * 8;
bool has_alpha = (header[8] & 8) != 0;
if (24 == bpp && has_alpha)
bpp = 32;
return new MrlMetaData {
Width = header.ToUInt32 (0x10),
Height = header.ToUInt32 (0x14),
BPP = bpp,
HasAlpha = has_alpha,
};
}
public override ImageData Read (IBinaryStream file, ImageMetaData info)
{
var meta = (MrlMetaData)info;
BitmapPalette palette = null;
file.Position = 0x18;
if (8 == info.BPP)
palette = ReadPalette (file.AsStream);
int stride = info.iWidth * (info.BPP / 8);
int channel_size = info.iWidth * info.iHeight;
var pixels = new byte[stride * info.iHeight];
var input_length = (int)(file.Length - file.Position);
var input = file.ReadBytes (input_length);
DecryptInput (input, 8);
MrlDecompress (input, pixels);
RestoreOutput (pixels);
byte[] image;
if (8 == info.BPP)
{
if (!meta.HasAlpha)
return ImageData.CreateFlipped (info, PixelFormats.Indexed8, palette, pixels, stride);
stride = info.iWidth * 4;
image = new byte[stride * info.iHeight];
int src = 0;
int asrc = channel_size;
var colors = palette.Colors;
for (int dst = 0; dst < image.Length; dst += 4)
{
byte c = pixels[src++];
image[dst ] = colors[c].B;
image[dst+1] = colors[c].G;
image[dst+2] = colors[c].R;
image[dst+3] = pixels[asrc++];
}
}
else
{
image = new byte[pixels.Length];
int channels = info.BPP / 8;
int src = 0;
for (int c = 0; c < channels; ++c)
{
int dst = c;
for (int i = 0; i < channel_size; ++i)
{
image[dst] = pixels[src++];
dst += channels;
}
}
}
PixelFormat format = meta.HasAlpha ? PixelFormats.Bgra32 : PixelFormats.Bgr24;
return ImageData.CreateFlipped (info, format, palette, image, stride);
}
public override void Write (Stream file, ImageData image)
{
throw new System.NotImplementedException ("MrlFormat.Write not implemented");
}
internal static void DecryptInput (byte[] data, byte key)
{
for (int i = 0; i < data.Length; ++i)
{
data[i] ^= key++;
}
}
internal static void MrlDecompress (byte[] input, byte[] output)
{
int src = 0;
int dst = 0;
while (src < input.Length && dst < output.Length)
{
byte p = input[src++];
if (p != 0)
{
output[dst++] = p;
}
else
{
int count = 1;
do
{
p = input[src++];
count += p;
}
while (0xFF == p);
dst += count;
}
}
}
internal static void RestoreOutput (byte[] data)
{
byte key = data[0];
for (int i = 1; i < data.Length; ++i)
{
data[i] ^= key;
key = data[i];
}
}
}
}

View File

@ -160,7 +160,7 @@ namespace GameRes.Formats.Bom
for (int i = 0; i <= 316; ++i) for (int i = 0; i <= 316; ++i)
{ {
v4 = dword_6FF464[v1] + dword_6FF468[v1]; v4 = dword_6FF464[v1] + dword_6FF468[v1];
dword_709870[v1] = v2; dword_70986C[v1 + 1] = v2;
dword_6FF95C[i] = v4; dword_6FF95C[i] = v4;
dword_704360[i] = v1; dword_704360[i] = v1;
dword_70986C[v1] = v2; dword_70986C[v1] = v2;
@ -175,9 +175,13 @@ namespace GameRes.Formats.Bom
dword_6FFE50 = 0xFFFF; dword_6FFE50 = 0xFFFF;
} }
int[] dword_704360 = new int[317];
int[] dword_6FF95C = new int[317];
int[] dword_70986C = new int[634];
int sub_408BE0 () int sub_408BE0 ()
{ {
for (int i = dword_704850; i < 635; i = dword_703E68[GetNextBit() + i]) for (int i = dword_704360[316]; i < 635; i = dword_703E68[GetNextBit() + i])
; ;
int ctl = i - 635; int ctl = i - 635;
sub_408C80 (ctl); sub_408C80 (ctl);
@ -210,7 +214,7 @@ namespace GameRes.Formats.Bom
int v8; // eax@7 int v8; // eax@7
int v9; // esi@9 int v9; // esi@9
if (dword_6FFE4C == 0x8000) if (dword_6FF95C[316] == 0x8000)
sub_408D50(); sub_408D50();
int v1 = dword_70A258[a1]; int v1 = dword_70A258[a1];
do do
@ -251,6 +255,98 @@ namespace GameRes.Formats.Bom
while (v1 != 0); while (v1 != 0);
} }
void sub_408D50 ()
{
int v3; // ecx@2
int v4; // edi@3
int v5; // ecx@5
int *v6; // ebx@5
unsigned int v7; // eax@6
int *v8; // edx@6
int v9; // ecx@6
int *v10; // edi@6
unsigned int v11; // ebp@7
int v12; // ecx@8
int *i; // edi@8
int *v14; // eax@10
int *v15; // ecx@10
int v16; // edx@13
int *v17; // ecx@13
int v18; // eax@14
int v19; // [sp+10h] [bp-8h]@5
signed int v20; // [sp+14h] [bp-4h]@5
int v1 = 0;
int v2 = 0;
for (int i = 0; i < 635; ++i)
{
int v3 = dword_703E68[i];
if (v3 >= 635)
{
v4 = dword_6FF464[i];
dword_703E68[v2] = v3;
dword_6FF464[v2] = (int)((uint)(v4 + 1) >> 1);
++v2;
}
}
int v5 = 318;
v19 = 0;
v20 = 318;
v6 = dword_6FF464;
do
{
v7 = *v6 + v6[1];
v8 = &dword_6FF95C[v1];
v9 = v5 - 1;
v10 = &dword_6FF95C[v1 - 1];
dword_6FF95C[v1] = v7;
if ( v7 < *v10 )
{
do
{
v11 = *(v10 - 1);
--v10;
--v9;
}
while ( v7 < v11 );
}
v12 = v9 + 1;
for ( i = &dword_6FF464[v12]; v8 > i; --v8 )
*v8 = *(v8 - 1);
*i = v7;
v14 = &dword_704360[v1];
v15 = &dword_703E68[v12];
if ( &dword_704360[v1] > v15 )
{
do
{
*v14 = *(v14 - 1);
--v14;
}
while ( v14 > v15 );
}
v6 += 2;
*v15 = v19;
++v1;
v5 = v20 + 1;
v19 += 2;
++v20;
}
while ( v1 < 317 );
v16 = 0;
v17 = dword_703E68;
do
{
v18 = *v17;
if ( *v17 < 635 )
dword_70986C[v18 + 1] = v16;
dword_70986C[v18] = v16;
++v17;
++v16;
}
while ( (signed int)v17 < (signed int)&unk_704854 );
}
void PutByte (int a1) void PutByte (int a1)
{ {
if (dword_6FF460 != 0) if (dword_6FF460 != 0)

69
Legacy/Dall/ArcPEL.cs Normal file
View File

@ -0,0 +1,69 @@
//! \file ArcPEL.cs
//! \date 2019 May 28
//! \brief Dall resource archive.
//
// Copyright (C) 2019 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.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
namespace GameRes.Formats.Dall
{
[Export(typeof(ArchiveFormat))]
public class PelOpener : ArchiveFormat
{
public override string Tag { get { return "PEL"; } }
public override string Description { get { return "Dall resource archive"; } }
public override uint Signature { get { return 0; } }
public override bool IsHierarchic { get { return false; } }
public override bool CanWrite { get { return false; } }
public override ArcFile TryOpen (ArcView file)
{
if (!file.Name.HasExtension ("PEL"))
return null;
int count = file.View.ReadInt16 (0);
if (!IsSaneCount (count))
return null;
using (var input = file.CreateStream())
{
input.Position = 2;
var dir = new List<Entry> (count);
for (int i = 0; i < count; ++i)
{
var name = input.ReadCString (0x14);
uint size = input.ReadUInt32();
var entry = Create<Entry> (name);
entry.Offset = input.Position;
entry.Size = size;
if (!entry.CheckPlacement (file.MaxOffset))
return null;
dir.Add (entry);
input.Seek (size, SeekOrigin.Current);
}
return new ArcFile (file, this, dir);
}
}
}
}

View File

@ -32,6 +32,7 @@ using System.Windows.Media.Imaging;
using GameRes.Compression; using GameRes.Compression;
// [000225][Discovery] Tsukiyo no Hitomi wa Kurenai ni // [000225][Discovery] Tsukiyo no Hitomi wa Kurenai ni
// [001102][Discovery] Twins Rhapsody
namespace GameRes.Formats.Discovery namespace GameRes.Formats.Discovery
{ {
@ -135,8 +136,8 @@ namespace GameRes.Formats.Discovery
entry.BodySize = index.ToUInt32 (index_offset+4); entry.BodySize = index.ToUInt32 (index_offset+4);
entry.BodyUnpacked = index.ToUInt32 (index_offset+8); entry.BodyUnpacked = index.ToUInt32 (index_offset+8);
entry.BodyOffset = index.ToUInt32 (index_offset+0xC); entry.BodyOffset = index.ToUInt32 (index_offset+0xC);
entry.HeaderUnpacked = index.ToUInt32 (index_offset+0x10); entry.HeaderSize = index.ToUInt32 (index_offset+0x10);
entry.HeaderSize = index.ToUInt32 (index_offset+0x14); entry.HeaderUnpacked = index.ToUInt32 (index_offset+0x14);
entry.Offset = index.ToUInt32 (index_offset+0x18); entry.Offset = index.ToUInt32 (index_offset+0x18);
entry.Size = entry.HeaderSize + entry.BodySize; entry.Size = entry.HeaderSize + entry.BodySize;
entry.UnpackedSize = entry.HeaderUnpacked + entry.BodyUnpacked; entry.UnpackedSize = entry.HeaderUnpacked + entry.BodyUnpacked;
@ -270,16 +271,7 @@ namespace GameRes.Formats.Discovery
public int Stride { get; private set; } public int Stride { get; private set; }
public BitmapPalette Palette { get; private set; } public BitmapPalette Palette { get; private set; }
public ImageData Image { public ImageData Image { get { return m_image ?? (m_image = Unpack()); } }
get {
if (null == m_image)
{
Unpack();
m_image = ImageData.CreateFlipped (Info, Format, Palette, m_output, Stride);
}
return m_image;
}
}
public BDataDecoder (ArcFile arc, BDataEntry entry) public BDataDecoder (ArcFile arc, BDataEntry entry)
{ {
@ -289,14 +281,17 @@ namespace GameRes.Formats.Discovery
if (entry.Extra > 0) if (entry.Extra > 0)
total_size += 10 * (uint)entry.Extra + 2; total_size += 10 * (uint)entry.Extra + 2;
Stride = ((int)entry.Width * entry.BPP / 8 + 3) & ~3; Stride = ((int)entry.Width * entry.BPP / 8 + 3) & ~3;
Format = PixelFormats.Bgr24; if (8 == entry.BPP)
Format = PixelFormats.Indexed8;
else
Format = PixelFormats.Bgr24;
m_output = new byte[Stride * (int)entry.Height]; m_output = new byte[Stride * (int)entry.Height];
m_colors = entry.Colors; m_colors = entry.Colors;
m_extra = entry.Extra; m_extra = entry.Extra;
m_input = arc.File.CreateStream (entry.Offset, total_size); m_input = arc.File.CreateStream (entry.Offset, total_size);
} }
private void Unpack () private ImageData Unpack ()
{ {
m_input.Position = 0; m_input.Position = 0;
if (m_colors > 0) if (m_colors > 0)
@ -305,6 +300,7 @@ namespace GameRes.Formats.Discovery
m_input.Seek (10 * m_extra + 2, SeekOrigin.Current); m_input.Seek (10 * m_extra + 2, SeekOrigin.Current);
using (var lzss = new LzssStream (m_input.AsStream, LzssMode.Decompress, true)) using (var lzss = new LzssStream (m_input.AsStream, LzssMode.Decompress, true))
lzss.Read (m_output, 0, m_output.Length); lzss.Read (m_output, 0, m_output.Length);
return ImageData.CreateFlipped (Info, Format, Palette, m_output, Stride);
} }
bool m_disposed = false; bool m_disposed = false;

67
Legacy/Eye/ImageCSF.cs Normal file
View File

@ -0,0 +1,67 @@
//! \file ImageCSF.cs
//! \date 2019 May 28
//! \brief Compressed bitmap format.
//
// Copyright (C) 2019 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.ComponentModel.Composition;
using System.IO;
using System.Windows.Media;
using GameRes.Compression;
namespace GameRes.Formats.Eye
{
[Export(typeof(ImageFormat))]
public class CsfFormat : ImageFormat
{
public override string Tag { get { return "CSF"; } }
public override string Description { get { return "Compressed bitmap format"; } }
public override uint Signature { get { return 0; } }
public override ImageMetaData ReadMetaData (IBinaryStream file)
{
var header = file.ReadHeader (0xB);
if (!header.AsciiEqual ("CSF"))
return null;
using (var input = UnpackedStream (file))
return Bmp.ReadMetaData (input);
}
public override ImageData Read (IBinaryStream file, ImageMetaData info)
{
using (var input = UnpackedStream (file))
return Bmp.Read (input, info);
}
IBinaryStream UnpackedStream (IBinaryStream input)
{
input.Position = 0xB;
var unpacked = new LzssStream (input.AsStream, LzssMode.Decompress, true);
return new BinaryStream (unpacked, input.Name);
}
public override void Write (Stream file, ImageData image)
{
throw new System.NotImplementedException ("CsfFormat.Write not implemented");
}
}
}

View File

@ -70,6 +70,7 @@
<Compile Include="Aaru\ImageBM2.cs" /> <Compile Include="Aaru\ImageBM2.cs" />
<Compile Include="Acme\ImageARD.cs" /> <Compile Include="Acme\ImageARD.cs" />
<Compile Include="Acme\ImagePMG.cs" /> <Compile Include="Acme\ImagePMG.cs" />
<Compile Include="ADVGSys\ImageBMP.cs" />
<Compile Include="Ags32i\AudioAGS.cs" /> <Compile Include="Ags32i\AudioAGS.cs" />
<Compile Include="Ags32i\ImageGSS.cs" /> <Compile Include="Ags32i\ImageGSS.cs" />
<Compile Include="Airyu\ArcCHR.cs" /> <Compile Include="Airyu\ArcCHR.cs" />
@ -78,10 +79,14 @@
<Compile Include="AlphaSystem\ArcPAK.cs" /> <Compile Include="AlphaSystem\ArcPAK.cs" />
<Compile Include="AlphaSystem\ImageSFG.cs" /> <Compile Include="AlphaSystem\ImageSFG.cs" />
<Compile Include="Alterna\ArcBIN.cs" /> <Compile Include="Alterna\ArcBIN.cs" />
<Compile Include="Aos\ArcDAT.cs" />
<Compile Include="Aquarium\ArcAAP.cs" /> <Compile Include="Aquarium\ArcAAP.cs" />
<Compile Include="Aquarium\ArcCPA.cs" /> <Compile Include="Aquarium\ArcCPA.cs" />
<Compile Include="Aquarium\ImageCP2.cs" /> <Compile Include="Aquarium\ImageCP2.cs" />
<Compile Include="Ark\ImageCMP.cs" /> <Compile Include="Ark\ImageCMP.cs" />
<Compile Include="Artel\ArcPFD.cs" />
<Compile Include="Artel\AudioMUW.cs" />
<Compile Include="Artel\ImageMRL.cs" />
<Compile Include="Asura\ArcPAK.cs" /> <Compile Include="Asura\ArcPAK.cs" />
<Compile Include="Asura\ImageMTG.cs" /> <Compile Include="Asura\ImageMTG.cs" />
<Compile Include="BRoom\ArcCPC.cs" /> <Compile Include="BRoom\ArcCPC.cs" />
@ -90,9 +95,11 @@
<Compile Include="BRoom\ImageERP.cs" /> <Compile Include="BRoom\ImageERP.cs" />
<Compile Include="Brownie\ImageNGC.cs" /> <Compile Include="Brownie\ImageNGC.cs" />
<Compile Include="Brownie\ImageNGW.cs" /> <Compile Include="Brownie\ImageNGW.cs" />
<Compile Include="Dall\ArcPEL.cs" />
<Compile Include="DigitalMonkey\ArcDM.cs" /> <Compile Include="DigitalMonkey\ArcDM.cs" />
<Compile Include="DigitalMonkey\ImagePKT.cs" /> <Compile Include="DigitalMonkey\ImagePKT.cs" />
<Compile Include="Electriciteit\ArcPKK.cs" /> <Compile Include="Electriciteit\ArcPKK.cs" />
<Compile Include="Eye\ImageCSF.cs" />
<Compile Include="FazeX\ImageFGP.cs" /> <Compile Include="FazeX\ImageFGP.cs" />
<Compile Include="HillField\ImageIMA.cs" /> <Compile Include="HillField\ImageIMA.cs" />
<Compile Include="HillField\ImageIMG.cs" /> <Compile Include="HillField\ImageIMG.cs" />
@ -124,6 +131,9 @@
<Compile Include="Powerd\ImageNCL.cs" /> <Compile Include="Powerd\ImageNCL.cs" />
<Compile Include="PrimeSoft\ImageTHP.cs" /> <Compile Include="PrimeSoft\ImageTHP.cs" />
<Compile Include="ProjectMyu\ImageGAM.cs" /> <Compile Include="ProjectMyu\ImageGAM.cs" />
<Compile Include="Ransel\ArcBCD.cs" />
<Compile Include="Regrips\AudioWRG.cs" />
<Compile Include="Regrips\ImagePRG.cs" />
<Compile Include="Rina\ImageRAD.cs" /> <Compile Include="Rina\ImageRAD.cs" />
<Compile Include="RSystem\ArcRAD.cs" /> <Compile Include="RSystem\ArcRAD.cs" />
<Compile Include="RSystem\ImageRSG.cs" /> <Compile Include="RSystem\ImageRSG.cs" />
@ -217,6 +227,8 @@
<Compile Include="Nekotaro\ArcNSC.cs" /> <Compile Include="Nekotaro\ArcNSC.cs" />
<Compile Include="Nekotaro\ImageGCmp.cs" /> <Compile Include="Nekotaro\ImageGCmp.cs" />
<Compile Include="PlanTech\ArcPAC.cs" /> <Compile Include="PlanTech\ArcPAC.cs" />
<Compile Include="Zone\ArcPKD.cs" />
<Compile Include="Zone\ImageBM_.cs" />
<None Include="PlanTech\ImagePAC.cs" /> <None Include="PlanTech\ImagePAC.cs" />
<Compile Include="Pochette\ImageGDT.cs" /> <Compile Include="Pochette\ImageGDT.cs" />
<Compile Include="ProjectMyu\ImageKGR.cs" /> <Compile Include="ProjectMyu\ImageKGR.cs" />
@ -260,6 +272,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Bom\" /> <Folder Include="Bom\" />
<Folder Include="HyperWorks\" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>

View File

@ -29,6 +29,7 @@ using System.ComponentModel.Composition;
using System.IO; using System.IO;
using GameRes.Compression; using GameRes.Compression;
// [991203][Libido] Ren'Ai Kumikyoku
// [030228][Libido] Libido 7 DVD // [030228][Libido] Libido 7 DVD
namespace GameRes.Formats.Libido namespace GameRes.Formats.Libido
@ -48,27 +49,34 @@ namespace GameRes.Formats.Libido
if (!IsSaneCount (count)) if (!IsSaneCount (count))
return null; return null;
const int name_buf_size = 0x14;
var name_buf = new byte[name_buf_size];
var is_name_encrypted = new Lazy<bool> (() => -1 != Array.IndexOf<byte> (name_buf, 0xFF, 0, name_buf_size));
uint index_offset = 4; uint index_offset = 4;
var name_buf = new byte[0x14];
var dir = new List<Entry> (count); var dir = new List<Entry> (count);
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
{ {
file.View.Read (index_offset, name_buf, 0, 0x14); file.View.Read (index_offset, name_buf, 0, name_buf_size);
int j; int j;
for (j = 0; j < 0x14; ++j) if (is_name_encrypted.Value)
{ {
name_buf[j] ^= 0xFF; for (j = 0; j < name_buf_size; ++j)
if (0 == name_buf[j]) {
break; name_buf[j] ^= 0xFF;
if (0 == name_buf[j])
break;
}
} }
if (0 == j || -1 != Array.IndexOf<byte> (name_buf, 0xFF, 0, j)) else
j = Array.IndexOf<byte> (name_buf, 0, 0, name_buf_size);
if (j <= 0 || -1 != Array.IndexOf<byte> (name_buf, 0xFF, 0, j))
return null; return null;
var name = Encodings.cp932.GetString (name_buf, 0, j); var name = Encodings.cp932.GetString (name_buf, 0, j);
var entry = Create<PackedEntry> (name); var entry = Create<PackedEntry> (name);
entry.UnpackedSize = file.View.ReadUInt32 (index_offset+0x14); entry.UnpackedSize = file.View.ReadUInt32 (index_offset+0x14);
entry.Size = file.View.ReadUInt32 (index_offset+0x18); entry.Size = file.View.ReadUInt32 (index_offset+0x18);
entry.Offset = file.View.ReadUInt32 (index_offset+0x1C); entry.Offset = file.View.ReadUInt32 (index_offset+0x1C);
if (!entry.CheckPlacement (file.MaxOffset)) if (entry.Offset <= index_offset || !entry.CheckPlacement (file.MaxOffset))
return null; return null;
entry.IsPacked = entry.Size != entry.UnpackedSize; entry.IsPacked = entry.Size != entry.UnpackedSize;
dir.Add (entry); dir.Add (entry);

76
Legacy/Ransel/ArcBCD.cs Normal file
View File

@ -0,0 +1,76 @@
//! \file ArcBCD.cs
//! \date 2019 Jun 02
//! \brief ransel engine resource archive.
//
// Copyright (C) 2019 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.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
namespace GameRes.Formats.Ransel
{
[Export(typeof(ArchiveFormat))]
public class BcdOpener : ArchiveFormat
{
public override string Tag { get { return "BCD"; } }
public override string Description { get { return "ransel engine resource archive"; } }
public override uint Signature { get { return 0x616E6942; } } // 'BinaryCombineData'
public override bool IsHierarchic { get { return false; } }
public override bool CanWrite { get { return false; } }
public override ArcFile TryOpen (ArcView file)
{
if (!file.View.AsciiEqual (0, "BinaryCombineData"))
return null;
var bcl_name = Path.ChangeExtension (file.Name, "bcl");
using (var bcl = VFS.OpenStream (bcl_name))
using (var index = new StreamReader (bcl, Encodings.cp932))
{
if (index.ReadLine() != "[BinaryCombineData]")
return null;
var filename = index.ReadLine();
if (!VFS.IsPathEqualsToFileName (file.Name, filename))
return null;
index.ReadLine();
var dir = new List<Entry>();
while ((filename = index.ReadLine()) != null)
{
if (!filename.StartsWith ("[") || !filename.EndsWith ("]"))
return null;
filename = filename.Substring (1, filename.Length-2);
var offset = index.ReadLine();
var size = index.ReadLine();
index.ReadLine();
var entry = Create<Entry> (filename);
entry.Offset = UInt32.Parse (offset);
entry.Size = UInt32.Parse (size);
if (!entry.CheckPlacement (file.MaxOffset))
return null;
dir.Add (entry);
}
return new ArcFile (file, this, dir);
}
}
}
}

View File

@ -0,0 +1,65 @@
//! \file AudioWRG.cs
//! \date 2019 May 05
//! \brief Regrips obfuscated audio.
//
// Copyright (C) 2019 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.ComponentModel.Composition;
namespace GameRes.Formats.Regrips
{
[Export(typeof(AudioFormat))]
public class WrgAudio : AudioFormat
{
public override string Tag { get { return "WRG"; } }
public override string Description { get { return "Regrips encrypted WAVE file"; } }
public override uint Signature { get { return 0xB9B9B6AD; } }
public override bool CanWrite { get { return false; } }
public override SoundInput TryOpen (IBinaryStream file)
{
var input = new XoredStream (file.AsStream, 0xFF);
return Wav.TryOpen (new BinaryStream (input, file.Name));
}
}
[Export(typeof(AudioFormat))]
public class MrgAudio : AudioFormat
{
public override string Tag { get { return "MRG"; } }
public override string Description { get { return "Regrips encrypted MP3 file"; } }
public override uint Signature { get { return 0; } }
public override bool CanWrite { get { return false; } }
static readonly ResourceInstance<AudioFormat> Mp3Format = new ResourceInstance<AudioFormat> ("MP3");
public override SoundInput TryOpen (IBinaryStream file)
{
var header = file.ReadHeader (2);
if (header[0] != 0)
return null;
file.Position = 0;
var input = new XoredStream (file.AsStream, 0xFF);
return Mp3Format.Value.TryOpen (new BinaryStream (input, file.Name));
}
}
}

View File

@ -0,0 +1,93 @@
//! \file ImagePRG.cs
//! \date 2019 May 05
//! \brief Regrips obfuscated image.
//
// Copyright (C) 2019 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.ComponentModel.Composition;
using System.IO;
using System.Windows.Media;
namespace GameRes.Formats.Regrips
{
[Export(typeof(ImageFormat))]
public class PrgFormat : ImageFormat
{
public override string Tag { get { return "PRG"; } }
public override string Description { get { return "Regrips encrypted image format"; } }
public override uint Signature { get { return 0xB8B1AF76; } }
public override bool CanWrite { get { return false; } }
public override ImageMetaData ReadMetaData (IBinaryStream file)
{
using (var input = DecryptStream (file))
return Png.ReadMetaData (input);
}
public override ImageData Read (IBinaryStream file, ImageMetaData info)
{
using (var input = DecryptStream (file))
return Png.Read (input, info);
}
internal IBinaryStream DecryptStream (IBinaryStream input)
{
var stream = new XoredStream (input.AsStream, 0xFF, true);
return new BinaryStream (stream, input.Name);
}
public override void Write (Stream file, ImageData image)
{
throw new System.NotImplementedException ("PrgFormat.Write not implemented");
}
}
[Export(typeof(ImageFormat))]
public class BrgFormat : PrgFormat
{
public override string Tag { get { return "BRG"; } }
public override string Description { get { return "Regrips encrypted bitmap"; } }
public override uint Signature { get { return 0; } }
public override bool CanWrite { get { return false; } }
public override ImageMetaData ReadMetaData (IBinaryStream file)
{
var header = file.ReadHeader (2);
if (header[0] != 0xBD || header[1] != 0xB2)
return null;
file.Position = 0;
using (var input = DecryptStream (file))
return Bmp.ReadMetaData (input);
}
public override ImageData Read (IBinaryStream file, ImageMetaData info)
{
using (var input = DecryptStream (file))
return Bmp.Read (input, info);
}
public override void Write (Stream file, ImageData image)
{
throw new System.NotImplementedException ("BrgFormat.Write not implemented");
}
}
}

70
Legacy/Zone/ArcPKD.cs Normal file
View File

@ -0,0 +1,70 @@
//! \file ArcPKD.cs
//! \date 2019 Jun 25
//! \brief Zone resource archive.
//
// Copyright (C) 2019 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.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
namespace GameRes.Formats.Zone
{
// [991118][Zone] Guren
[Export(typeof(ArchiveFormat))]
public class PkdOpener : ArchiveFormat
{
public override string Tag { get { return "PKD/ZONE"; } }
public override string Description { get { return "Zone resource archive"; } }
public override uint Signature { get { return 1; } }
public override bool IsHierarchic { get { return false; } }
public override bool CanWrite { get { return false; } }
public override ArcFile TryOpen (ArcView file)
{
if (!file.Name.HasExtension (".pkd"))
return null;
int count = file.View.ReadInt32 (4);
if (!IsSaneCount (count))
return null;
uint data_offset = file.View.ReadUInt32 (0xC);
uint index_offset = 0x10;
var dir = new List<Entry> (count);
for (int i = 0; i < count; ++i)
{
var name = file.View.ReadString (index_offset, 0x20);
if (string.IsNullOrWhiteSpace (name))
return null;
var entry = Create<Entry> (name);
entry.Offset = file.View.ReadUInt32 (index_offset+0x20) + data_offset;
entry.Size = file.View.ReadUInt32 (index_offset+0x24);
if (!entry.CheckPlacement (file.MaxOffset))
return null;
dir.Add (entry);
index_offset += 0x2C;
}
return new ArcFile (file, this, dir);
}
}
}

117
Legacy/Zone/ImageBM_.cs Normal file
View File

@ -0,0 +1,117 @@
//! \file ImageBM_.cs
//! \date 2019 Jun 25
//! \brief Zone compressed image.
//
// Copyright (C) 2019 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.ComponentModel.Composition;
using System.IO;
using System.Windows.Media;
namespace GameRes.Formats.Zone
{
internal class Bm_MetaData : ImageMetaData
{
public bool IsCompressed;
public byte RleFlag;
}
[Export(typeof(ImageFormat))]
public class Bm_Format : ImageFormat
{
public override string Tag { get { return "BM_/ZONE"; } }
public override string Description { get { return "Zone compressed image"; } }
public override uint Signature { get { return 0; } }
public override ImageMetaData ReadMetaData (IBinaryStream file)
{
if (!file.Name.HasExtension (".bm_"))
return null;
var header = file.ReadHeader (0x18);
int signature = header.ToInt32 (0);
if (signature != 0 && signature != 1)
return null;
file.Position = 0x418;
return new Bm_MetaData {
Width = header.ToUInt32 (4),
Height = header.ToUInt32 (8),
BPP = 8,
IsCompressed = signature != 0,
RleFlag = file.ReadUInt8(),
};
}
public override ImageData Read (IBinaryStream file, ImageMetaData info)
{
var meta = (Bm_MetaData)info;
file.Position = 0x18;
var palette = ReadPalette (file.AsStream);
var pixels = new byte[info.Width * info.Height];
file.Position = 0x424;
if (meta.IsCompressed)
ReadRle (file, pixels, meta.RleFlag);
else
file.Read (pixels, 0, pixels.Length);
if (meta.IsCompressed)
return ImageData.Create (info, PixelFormats.Indexed8, palette, pixels);
else
return ImageData.CreateFlipped (info, PixelFormats.Indexed8, palette, pixels, info.iWidth);
}
void ReadRle (IBinaryStream input, byte[] output, byte rle_flag)
{
int dst = 0;
while (dst < output.Length)
{
byte b = input.ReadUInt8();
if (b != rle_flag)
{
output[dst++] = b;
continue;
}
b = input.ReadUInt8();
if (0 == b)
{
output[dst++] = rle_flag;
continue;
}
int count = 0;
while (1 == b)
{
count += 0x100;
b = input.ReadUInt8();
}
count += b;
if (b != 0)
input.ReadByte();
b = input.ReadUInt8();
while (count --> 0)
output[dst++] = b;
}
}
public override void Write (Stream file, ImageData image)
{
throw new System.NotImplementedException ("Bm_Format.Write not implemented");
}
}
}