GARbro-mirror/GameRes/Image.cs

120 lines
3.5 KiB
C#
Raw Normal View History

2014-07-22 03:26:28 +08:00
//! \file Image.cs
//! \date Tue Jul 01 11:29:52 2014
//! \brief image class.
//
using System.IO;
using System.Windows.Media.Imaging;
namespace GameRes
{
public class ImageMetaData
{
public uint Width { get; set; }
public uint Height { get; set; }
public int OffsetX { get; set; }
public int OffsetY { get; set; }
public int BPP { get; set; }
}
public class ImageEntry : Entry
{
public override string Type { get { return "image"; } }
}
public class ImageData
{
private BitmapSource m_bitmap;
public BitmapSource Bitmap { get { return m_bitmap; } }
public uint Width { get { return (uint)m_bitmap.PixelWidth; } }
public uint Height { get { return (uint)m_bitmap.PixelHeight; } }
public int OffsetX { get; set; }
public int OffsetY { get; set; }
public int BPP { get { return m_bitmap.Format.BitsPerPixel; } }
public ImageData (BitmapSource data, ImageMetaData meta)
{
m_bitmap = data;
OffsetX = meta.OffsetX;
OffsetY = meta.OffsetY;
}
public ImageData (BitmapSource data, int x = 0, int y = 0)
{
m_bitmap = data;
OffsetX = x;
OffsetY = y;
}
}
public abstract class ImageFormat : IResource
{
public override string Type { get { return "image"; } }
2014-07-25 12:56:32 +08:00
public abstract ImageMetaData ReadMetaData (Stream file);
public abstract ImageData Read (Stream file, ImageMetaData info);
public abstract void Write (Stream file, ImageData bitmap);
public static ImageData Read (Stream file)
2014-07-22 03:26:28 +08:00
{
bool need_dispose = false;
try
{
if (!file.CanSeek)
{
var stream = new MemoryStream();
file.CopyTo (stream);
file = stream;
need_dispose = true;
}
2014-07-25 12:56:32 +08:00
var format = FindFormat (file);
if (null == format)
return null;
file.Position = 0;
return format.Item1.Read (file, format.Item2);
2014-07-22 03:26:28 +08:00
}
finally
{
if (need_dispose)
file.Dispose();
}
}
2014-07-25 12:56:32 +08:00
public static System.Tuple<ImageFormat, ImageMetaData> FindFormat (Stream file)
{
uint signature = FormatCatalog.ReadSignature (file);
for (;;)
{
var range = FormatCatalog.Instance.LookupSignature<ImageFormat> (signature);
foreach (var impl in range)
{
try
{
file.Position = 0;
ImageMetaData metadata = impl.ReadMetaData (file);
if (null != metadata)
return new System.Tuple<ImageFormat, ImageMetaData> (impl, metadata);
}
catch { }
}
if (0 == signature)
break;
signature = 0;
}
return null;
}
2014-07-22 03:26:28 +08:00
public override Entry CreateEntry ()
{
return new ImageEntry();
}
public bool IsBuiltin
{
get { return this.GetType().Assembly == typeof(ImageFormat).Assembly; }
}
}
}