mirror of
https://github.com/crskycode/GARbro.git
synced 2024-12-24 20:04:13 +08:00
DRG images implementation updates.
support for 8-bit images; support for alpha-channel in GGA0 images.
This commit is contained in:
parent
c641738821
commit
b33577c051
@ -2,7 +2,7 @@
|
||||
//! \date Fri Aug 22 05:58:40 2014
|
||||
//! \brief Digital Romance System image format implementation.
|
||||
//
|
||||
// Copyright (C) 2014 by morkt
|
||||
// Copyright (C) 2014-2015 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
|
||||
@ -45,7 +45,7 @@ namespace GameRes.Formats.DRS
|
||||
public DrgFormat ()
|
||||
{
|
||||
Extensions = new string[] { "drg", "ggd" };
|
||||
Signatures = new uint[] { ~0x4c4c5546u, ~0x45555254u, ~0x48474948u, ~0x47363532u };
|
||||
Signatures = new uint[] { ~0x4c4c5546u, ~0x45555254u, ~0x48474948u };
|
||||
}
|
||||
|
||||
public override void Write (Stream file, ImageData image)
|
||||
@ -65,22 +65,12 @@ namespace GameRes.Formats.DRS
|
||||
case 0x4c4c5546: /* fall through */
|
||||
case 0x45555254: bpp = 24; break;
|
||||
case 0x48474948: bpp = 16; break;
|
||||
case 0x47363532: bpp = 8; break;
|
||||
default: return null;
|
||||
}
|
||||
using (var input = new BinaryReader (stream, Encoding.ASCII, true))
|
||||
{
|
||||
uint width, height;
|
||||
if (8 != bpp)
|
||||
{
|
||||
width = input.ReadUInt16();
|
||||
height = input.ReadUInt16();
|
||||
}
|
||||
else
|
||||
{
|
||||
width = input.ReadUInt32();
|
||||
height = input.ReadUInt32();
|
||||
}
|
||||
uint width = input.ReadUInt16();
|
||||
uint height = input.ReadUInt16();
|
||||
return new ImageMetaData {
|
||||
Width = width,
|
||||
Height = height,
|
||||
@ -90,38 +80,6 @@ namespace GameRes.Formats.DRS
|
||||
}
|
||||
|
||||
public override ImageData Read (Stream file, ImageMetaData info)
|
||||
{
|
||||
BitmapSource bitmap;
|
||||
if (8 == info.BPP)
|
||||
bitmap = ReadIndexed (file, info);
|
||||
else
|
||||
bitmap = ReadTrue (file, info);
|
||||
bitmap.Freeze();
|
||||
return new ImageData (bitmap, info);
|
||||
}
|
||||
|
||||
private BitmapSource ReadIndexed (Stream file, ImageMetaData info)
|
||||
{
|
||||
file.Position = 44;
|
||||
PixelFormat format = PixelFormats.Indexed8;
|
||||
var palette_data = new byte[0x400];
|
||||
if (palette_data.Length != file.Read (palette_data, 0, palette_data.Length))
|
||||
throw new InvalidFormatException();
|
||||
var palette = new Color[256];
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
palette[i] = Color.FromRgb (palette_data[i*4+2], palette_data[i*4+1], palette_data[i*4]);
|
||||
}
|
||||
var bitmap_palette = new BitmapPalette (palette);
|
||||
file.Position += 4;
|
||||
int stride = (int)info.Width*((info.BPP+7)/8);
|
||||
|
||||
/* indexed GGD image is a LZSS-compressed stream */
|
||||
/* currently not implemented */
|
||||
throw new NotImplementedException ("DrgFormat.ReadIndexed not implemented");
|
||||
}
|
||||
|
||||
private BitmapSource ReadTrue (Stream file, ImageMetaData info)
|
||||
{
|
||||
file.Position = 8;
|
||||
PixelFormat format;
|
||||
@ -134,8 +92,10 @@ namespace GameRes.Formats.DRS
|
||||
var pixel_data = DecodeStream (file, stride*(int)info.Height);
|
||||
if (null == pixel_data)
|
||||
throw new InvalidFormatException();
|
||||
return BitmapSource.Create ((int)info.Width, (int)info.Height, 96, 96,
|
||||
format, null, pixel_data, stride);
|
||||
var bitmap = BitmapSource.Create ((int)info.Width, (int)info.Height, 96, 96,
|
||||
format, null, pixel_data, stride);
|
||||
bitmap.Freeze();
|
||||
return new ImageData (bitmap, info);
|
||||
}
|
||||
|
||||
byte[] DecodeStream (Stream input, int pixel_count)
|
||||
@ -458,6 +418,76 @@ namespace GameRes.Formats.DRS
|
||||
}
|
||||
}
|
||||
|
||||
internal class GgdMetaData : ImageMetaData
|
||||
{
|
||||
public uint HeaderSize;
|
||||
public uint BitmapSize;
|
||||
public bool Flipped;
|
||||
}
|
||||
|
||||
[Export(typeof(ImageFormat))]
|
||||
public class DrgIndexedFormat : ImageFormat
|
||||
{
|
||||
public override string Tag { get { return "DRG"; } }
|
||||
public override string Description { get { return "Digital Romance System indexed image format"; } }
|
||||
public override uint Signature { get { return ~0x47363532u; } } // '256G'
|
||||
|
||||
public DrgIndexedFormat ()
|
||||
{
|
||||
Extensions = new string[] { "ggd" };
|
||||
}
|
||||
|
||||
public override ImageMetaData ReadMetaData (Stream stream)
|
||||
{
|
||||
using (var input = new ArcView.Reader (stream))
|
||||
{
|
||||
input.ReadUInt32();
|
||||
var info = new GgdMetaData { BPP = 8 };
|
||||
info.HeaderSize = input.ReadUInt32();
|
||||
info.Width = input.ReadUInt32();
|
||||
int height = input.ReadInt32();
|
||||
if (height < 0)
|
||||
{
|
||||
height = -height;
|
||||
info.Flipped = true;
|
||||
}
|
||||
info.Height = (uint)height;
|
||||
input.ReadInt64();
|
||||
info.BitmapSize = input.ReadUInt32();
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
public override ImageData Read (Stream file, ImageMetaData info)
|
||||
{
|
||||
var meta = info as GgdMetaData;
|
||||
if (null == meta)
|
||||
throw new ArgumentException ("DrgIndexedFormat.Read should be supplied with GgdMetaData", "info");
|
||||
file.Position = meta.HeaderSize + 4;
|
||||
var palette_data = new byte[0x400];
|
||||
if (palette_data.Length != file.Read (palette_data, 0, palette_data.Length))
|
||||
throw new InvalidFormatException();
|
||||
var colors = new Color[256];
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
colors[i] = Color.FromRgb (palette_data[i*4+2], palette_data[i*4+1], palette_data[i*4]);
|
||||
}
|
||||
file.Seek (4, SeekOrigin.Current);
|
||||
int input_size = (int)(file.Length - file.Position);
|
||||
using (var reader = new LzssReader (file, input_size, (int)meta.BitmapSize))
|
||||
{
|
||||
reader.Unpack();
|
||||
var palette = new BitmapPalette (colors);
|
||||
return ImageData.Create (info, PixelFormats.Indexed8, palette, reader.Data);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Write (Stream file, ImageData image)
|
||||
{
|
||||
throw new NotImplementedException ("DrgIndexedFormat.Write not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
[Export(typeof(ImageFormat))]
|
||||
public class GgaFormat : ImageFormat
|
||||
{
|
||||
@ -465,8 +495,14 @@ namespace GameRes.Formats.DRS
|
||||
public override string Description { get { return "IKURA GDL image format"; } }
|
||||
public override uint Signature { get { return 0x30414747u; } } // 'GGA0'
|
||||
|
||||
public GgaFormat ()
|
||||
{
|
||||
Extensions = new string[] { "gg1", "gg2", "gg3" };
|
||||
}
|
||||
|
||||
internal class GgaMetaData : ImageMetaData
|
||||
{
|
||||
public uint Flags;
|
||||
public uint HeaderSize;
|
||||
public uint CompSize;
|
||||
}
|
||||
@ -486,7 +522,8 @@ namespace GameRes.Formats.DRS
|
||||
return new GgaMetaData {
|
||||
Width = LittleEndian.ToUInt16 (header, 8),
|
||||
Height = LittleEndian.ToUInt16 (header, 10),
|
||||
BPP = 32,
|
||||
BPP = header[14],
|
||||
Flags = header[15],
|
||||
HeaderSize = LittleEndian.ToUInt32 (header, 16),
|
||||
CompSize = LittleEndian.ToUInt32 (header, 20)
|
||||
};
|
||||
@ -499,10 +536,8 @@ namespace GameRes.Formats.DRS
|
||||
throw new ArgumentException ("GgaFormat.Read should be supplied with GgaMetaData", "info");
|
||||
file.Position = meta.HeaderSize;
|
||||
var pixel_data = DecodeStream (file, meta);
|
||||
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);
|
||||
PixelFormat format = 0 == (meta.Flags & 1) ? PixelFormats.Bgr32 : PixelFormats.Bgra32;
|
||||
return ImageData.Create (info, format, null, pixel_data);
|
||||
}
|
||||
|
||||
byte[] DecodeStream (Stream file, GgaMetaData meta)
|
||||
@ -511,7 +546,6 @@ namespace GameRes.Formats.DRS
|
||||
var output = new byte[meta.Width*meta.Height*4];
|
||||
using (var input = new BinaryReader (file, Encoding.ASCII, true))
|
||||
{
|
||||
var buf = new byte[4];
|
||||
var end_pos = input.BaseStream.Position + meta.CompSize;
|
||||
while (input.BaseStream.Position < end_pos)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user