mirror of
https://github.com/crskycode/GARbro.git
synced 2024-12-24 03:44: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 ()
|
||||
{
|
||||
Extensions = new string[] { "drg", "ggd" };
|
||||
Signatures = new uint[] { ~0x4c4c5546u, ~0x45555254u, ~0x48474948u, ~0x47363532u };
|
||||
}
|
||||
|
||||
@ -443,4 +444,227 @@ namespace GameRes.Formats.DRS
|
||||
#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