mirror of
https://github.com/crskycode/GARbro.git
synced 2024-12-24 20:04:13 +08:00
(MK2): added BPR01 decompressor.
This commit is contained in:
parent
834fc8631b
commit
e00dc73aad
@ -2,7 +2,7 @@
|
|||||||
//! \date Thu Aug 04 05:11:20 2016
|
//! \date Thu Aug 04 05:11:20 2016
|
||||||
//! \brief MAIKA resource archives.
|
//! \brief MAIKA resource archives.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2016 by morkt
|
// Copyright (C) 2016-2018 by morkt
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to
|
// of this software and associated documentation files (the "Software"), to
|
||||||
@ -94,11 +94,14 @@ namespace GameRes.Formats.Maika
|
|||||||
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
||||||
{
|
{
|
||||||
ushort signature = arc.File.View.ReadUInt16 (entry.Offset);
|
ushort signature = arc.File.View.ReadUInt16 (entry.Offset);
|
||||||
|
// C1/D1/E1/F1
|
||||||
if (0x3146 != signature && 0x3143 != signature && 0x3144 != signature && 0x3145 != signature)
|
if (0x3146 != signature && 0x3143 != signature && 0x3144 != signature && 0x3145 != signature)
|
||||||
return base.OpenEntry (arc, entry);
|
return base.OpenEntry (arc, entry);
|
||||||
uint packed_size = arc.File.View.ReadUInt32 (entry.Offset+2);
|
uint packed_size = arc.File.View.ReadUInt32 (entry.Offset+2);
|
||||||
if (packed_size < 14 || packed_size > entry.Size-10)
|
if (packed_size < 14 || packed_size > entry.Size-10)
|
||||||
return base.OpenEntry (arc, entry);
|
return base.OpenEntry (arc, entry);
|
||||||
|
|
||||||
|
// XXX scrambling might be applicable for 'E1' signatures only
|
||||||
var prefix = arc.File.View.ReadBytes (entry.Offset+10, 14);
|
var prefix = arc.File.View.ReadBytes (entry.Offset+10, 14);
|
||||||
byte t = prefix[7];
|
byte t = prefix[7];
|
||||||
prefix[7] = prefix[11];
|
prefix[7] = prefix[11];
|
||||||
@ -106,49 +109,89 @@ namespace GameRes.Formats.Maika
|
|||||||
t = prefix[9];
|
t = prefix[9];
|
||||||
prefix[9] = prefix[12];
|
prefix[9] = prefix[12];
|
||||||
prefix[12] = t;
|
prefix[12] = t;
|
||||||
|
|
||||||
Stream input = arc.File.CreateStream (entry.Offset+24, packed_size-14);
|
Stream input = arc.File.CreateStream (entry.Offset+24, packed_size-14);
|
||||||
input = new PrefixStream (prefix, input);
|
input = new PrefixStream (prefix, input);
|
||||||
input = new LzssStream (input);
|
input = new LzssStream (input);
|
||||||
|
|
||||||
var header = new byte[5];
|
var header = new byte[5];
|
||||||
input.Read (header, 0, 5);
|
input.Read (header, 0, 5);
|
||||||
if (!Binary.AsciiEqual (header, "BPR02"))
|
if (Binary.AsciiEqual (header, "BPR02"))
|
||||||
return new PrefixStream (header, input);
|
return new PackedStream<Bpr02Decompressor> (input);
|
||||||
using (input)
|
if (Binary.AsciiEqual (header, "BPR01"))
|
||||||
return Unpack (input);
|
return new PackedStream<Bpr01Decompressor> (input);
|
||||||
|
return new PrefixStream (header, input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal abstract class BprDecompressor : Decompressor
|
||||||
|
{
|
||||||
|
readonly byte m_rle_code;
|
||||||
|
IBinaryStream m_input;
|
||||||
|
|
||||||
|
protected BprDecompressor (byte rle_code)
|
||||||
|
{
|
||||||
|
m_rle_code = rle_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream Unpack (Stream input)
|
public override void Initialize (Stream input)
|
||||||
{
|
{
|
||||||
using (var reader = new ArcView.Reader (input))
|
m_input = new BinaryStream (input, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IEnumerator<int> Unpack ()
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
var output = new MemoryStream();
|
int ctl = m_input.ReadByte();
|
||||||
var buffer = new byte[0x10000];
|
if (-1 == ctl || 0xFF == ctl)
|
||||||
for (;;)
|
yield break;
|
||||||
|
int count = m_input.ReadInt32();
|
||||||
|
if (m_rle_code == ctl)
|
||||||
{
|
{
|
||||||
int ctl = input.ReadByte();
|
byte b = m_input.ReadUInt8();
|
||||||
if (-1 == ctl || 0xFF == ctl)
|
while (count --> 0)
|
||||||
break;
|
|
||||||
int count = reader.ReadInt32();
|
|
||||||
if (3 == ctl)
|
|
||||||
{
|
{
|
||||||
byte b = reader.ReadByte();
|
m_buffer[m_pos++] = b;
|
||||||
for (int i = 0; i < count; ++i)
|
if (0 == --m_length)
|
||||||
output.WriteByte (b);
|
yield return m_pos;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (count > 0)
|
|
||||||
{
|
|
||||||
int chunk = Math.Min (count, buffer.Length);
|
|
||||||
int read = reader.Read (buffer, 0, chunk);
|
|
||||||
output.Write (buffer, 0, read);
|
|
||||||
count -= chunk;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output.Position = 0;
|
else
|
||||||
return output;
|
{
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
int chunk = Math.Min (count, m_length);
|
||||||
|
int read = m_input.Read (m_buffer, m_pos, chunk);
|
||||||
|
count -= chunk;
|
||||||
|
m_pos += chunk;
|
||||||
|
m_length -= chunk;
|
||||||
|
if (0 == m_length)
|
||||||
|
yield return m_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool m_disposed = false;
|
||||||
|
protected override void Dispose (bool disposing)
|
||||||
|
{
|
||||||
|
if (!m_disposed)
|
||||||
|
{
|
||||||
|
if (m_input != null)
|
||||||
|
m_input.Dispose();
|
||||||
|
m_disposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class Bpr02Decompressor : BprDecompressor
|
||||||
|
{
|
||||||
|
public Bpr02Decompressor () : base (3) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class Bpr01Decompressor : BprDecompressor
|
||||||
|
{
|
||||||
|
public Bpr01Decompressor () : base (1) { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user