mirror of
https://github.com/crskycode/GARbro.git
synced 2024-12-25 20:34:13 +08:00
added GG2 image format.
This commit is contained in:
parent
cc44a73bc5
commit
797931eef8
@ -44,6 +44,7 @@ namespace GameRes.Formats.DRS
|
|||||||
|
|
||||||
public DrgFormat ()
|
public DrgFormat ()
|
||||||
{
|
{
|
||||||
|
Extensions = new string[] { "drg", "ggd" };
|
||||||
Signatures = new uint[] { ~0x4c4c5546u, ~0x45555254u, ~0x48474948u, ~0x47363532u };
|
Signatures = new uint[] { ~0x4c4c5546u, ~0x45555254u, ~0x48474948u, ~0x47363532u };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,4 +444,227 @@ namespace GameRes.Formats.DRS
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Export(typeof(ImageFormat))]
|
||||||
|
public class GgaFormat : ImageFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "GG2"; } }
|
||||||
|
public override string Description { get { return "IKURA GDL image format"; } }
|
||||||
|
public override uint Signature { get { return 0x30414747u; } } // 'GGA0'
|
||||||
|
|
||||||
|
internal class GgaMetaData : ImageMetaData
|
||||||
|
{
|
||||||
|
public uint HeaderSize;
|
||||||
|
public uint CompSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write (Stream file, ImageData image)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException ("GgaFormat.Write not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ImageMetaData ReadMetaData (Stream stream)
|
||||||
|
{
|
||||||
|
var header = new byte[24];
|
||||||
|
if (header.Length != stream.Read (header, 0, header.Length))
|
||||||
|
return null;
|
||||||
|
if (!Binary.AsciiEqual (header, "GGA00000"))
|
||||||
|
return null;
|
||||||
|
return new GgaMetaData {
|
||||||
|
Width = LittleEndian.ToUInt16 (header, 8),
|
||||||
|
Height = LittleEndian.ToUInt16 (header, 10),
|
||||||
|
BPP = 32,
|
||||||
|
HeaderSize = LittleEndian.ToUInt32 (header, 16),
|
||||||
|
CompSize = LittleEndian.ToUInt32 (header, 20)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ImageData Read (Stream file, ImageMetaData info)
|
||||||
|
{
|
||||||
|
var meta = info as GgaMetaData;
|
||||||
|
if (null == meta)
|
||||||
|
throw new ArgumentException ("GgaFormat.Read should be supplied with GgaMetaData", "info");
|
||||||
|
file.Position = meta.HeaderSize;
|
||||||
|
var pixel_data = DecodeStream (file, meta, (int)(meta.Width*meta.Height*4));
|
||||||
|
var bitmap = BitmapSource.Create ((int)info.Width, (int)info.Height, 96, 96,
|
||||||
|
PixelFormats.Bgra32, null, pixel_data, (int)info.Width*4);
|
||||||
|
bitmap.Freeze();
|
||||||
|
return new ImageData (bitmap, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] DecodeStream (Stream file, GgaMetaData meta, int pixel_count)
|
||||||
|
{
|
||||||
|
using (var input = new BinaryReader (file, Encoding.ASCII, true))
|
||||||
|
using (var output = new MemoryStream (pixel_count))
|
||||||
|
{
|
||||||
|
var buf = new byte[4];
|
||||||
|
uint isize = 0;
|
||||||
|
while (isize < meta.CompSize)
|
||||||
|
{
|
||||||
|
int ctrl = input.ReadByte();
|
||||||
|
++isize;
|
||||||
|
switch (ctrl)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
output.Position -= 4;
|
||||||
|
output.Read (buf, 0, 4);
|
||||||
|
byte i = input.ReadByte();
|
||||||
|
isize++;
|
||||||
|
for (int j = 0; j < i; ++j)
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
output.Position -= 4;
|
||||||
|
output.Read (buf, 0, 4);
|
||||||
|
int i = input.ReadUInt16();
|
||||||
|
isize += 2;
|
||||||
|
for (int j = 0; j < i; ++j)
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
byte l = input.ReadByte();
|
||||||
|
isize++;
|
||||||
|
var curpos = output.Position;
|
||||||
|
output.Position -= l << 2;
|
||||||
|
output.Read (buf, 0, 4);
|
||||||
|
output.Position = curpos;
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
int l = input.ReadUInt16();
|
||||||
|
isize += 2;
|
||||||
|
var curpos = output.Position;
|
||||||
|
output.Position -= l << 2;
|
||||||
|
output.Read (buf, 0, 4);
|
||||||
|
output.Position = curpos;
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
byte l = input.ReadByte();
|
||||||
|
var dstpos = output.Position - (l << 2);
|
||||||
|
int i = input.ReadByte();
|
||||||
|
isize += 2;
|
||||||
|
for (int j = 0; j < i; ++j)
|
||||||
|
{
|
||||||
|
var curpos = output.Position;
|
||||||
|
output.Position = dstpos;
|
||||||
|
dstpos += 4;
|
||||||
|
output.Read (buf, 0, 4);
|
||||||
|
output.Position = curpos;
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
byte l = input.ReadByte();
|
||||||
|
var dstpos = output.Position - (l << 2);
|
||||||
|
int i = input.ReadUInt16();
|
||||||
|
isize += 3;
|
||||||
|
for (int j = 0; j < i; ++j)
|
||||||
|
{
|
||||||
|
var curpos = output.Position;
|
||||||
|
output.Position = dstpos;
|
||||||
|
dstpos += 4;
|
||||||
|
output.Read (buf, 0, 4);
|
||||||
|
output.Position = curpos;
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6:
|
||||||
|
{
|
||||||
|
int l = input.ReadUInt16();
|
||||||
|
var dstpos = output.Position - (l << 2);
|
||||||
|
int i = input.ReadByte();
|
||||||
|
isize += 3;
|
||||||
|
for (int j = 0; j < i; ++j)
|
||||||
|
{
|
||||||
|
var curpos = output.Position;
|
||||||
|
output.Position = dstpos;
|
||||||
|
dstpos += 4;
|
||||||
|
output.Read (buf, 0, 4);
|
||||||
|
output.Position = curpos;
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 7:
|
||||||
|
{
|
||||||
|
int l = input.ReadUInt16();
|
||||||
|
var dstpos = output.Position - (l << 2);
|
||||||
|
int i = input.ReadUInt16();
|
||||||
|
isize += 4;
|
||||||
|
for (int j = 0; j < i; ++j)
|
||||||
|
{
|
||||||
|
var curpos = output.Position;
|
||||||
|
output.Position = dstpos;
|
||||||
|
dstpos += 4;
|
||||||
|
output.Read (buf, 0, 4);
|
||||||
|
output.Position = curpos;
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
var curpos = output.Position;
|
||||||
|
output.Position -= 4;
|
||||||
|
output.Read (buf, 0, 4);
|
||||||
|
output.Position = curpos;
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 9:
|
||||||
|
{
|
||||||
|
var curpos = output.Position;
|
||||||
|
output.Position -= meta.Width * 4;
|
||||||
|
output.Read (buf, 0, 4);
|
||||||
|
output.Position = curpos;
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x0a:
|
||||||
|
{
|
||||||
|
var curpos = output.Position;
|
||||||
|
output.Position -= meta.Width * 4 + 4;
|
||||||
|
output.Read (buf, 0, 4);
|
||||||
|
output.Position = curpos;
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x0b:
|
||||||
|
{
|
||||||
|
var curpos = output.Position;
|
||||||
|
output.Position -= meta.Width * 4 - 4;
|
||||||
|
output.Read (buf, 0, 4);
|
||||||
|
output.Position = curpos;
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
for (int i = ctrl - 11; i > 0; --i)
|
||||||
|
{
|
||||||
|
int read = input.Read (buf, 0, 4);
|
||||||
|
if (4 != read)
|
||||||
|
throw new InvalidFormatException ("Unexpected end of input");
|
||||||
|
output.Write (buf, 0, 4);
|
||||||
|
isize += 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output.GetBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user