mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-23 13:45:34 +08:00
(LimFormat): refined 16bpp images support.
This commit is contained in:
parent
3711e28d79
commit
2c82b05afa
@ -31,6 +31,11 @@ using GameRes.Utility;
|
||||
|
||||
namespace GameRes.Formats.Liar
|
||||
{
|
||||
internal class LimMetaData : ImageMetaData
|
||||
{
|
||||
public int Flags;
|
||||
}
|
||||
|
||||
[Export(typeof(ImageFormat))]
|
||||
public class LimFormat : ImageFormat
|
||||
{
|
||||
@ -42,14 +47,13 @@ namespace GameRes.Formats.Liar
|
||||
{
|
||||
if (0x4C != stream.ReadByte() || 0x4D != stream.ReadByte())
|
||||
return null;
|
||||
int flag = stream.ReadByte() & 0xF;
|
||||
if (flag != 2 && flag != 3)
|
||||
return null;
|
||||
stream.ReadByte();
|
||||
using (var file = new ArcView.Reader (stream))
|
||||
{
|
||||
int flag = file.ReadUInt16();
|
||||
if ((flag & 0xF) != 2 && (flag & 0xF) != 3)
|
||||
return null;
|
||||
int bpp = 0x10 == file.ReadUInt16() ? 16 : 32;
|
||||
var meta = new ImageMetaData { BPP = bpp };
|
||||
var meta = new LimMetaData { BPP = bpp, Flags = flag };
|
||||
file.ReadUInt16();
|
||||
meta.Width = file.ReadUInt32();
|
||||
meta.Height = file.ReadUInt32();
|
||||
@ -59,8 +63,7 @@ namespace GameRes.Formats.Liar
|
||||
|
||||
public override ImageData Read (Stream file, ImageMetaData info)
|
||||
{
|
||||
file.Position = 0x10;
|
||||
using (var reader = new Reader (file, info))
|
||||
using (var reader = new Reader (file, (LimMetaData)info))
|
||||
{
|
||||
reader.Unpack();
|
||||
return ImageData.Create (info, reader.Format, null, reader.Data);
|
||||
@ -81,16 +84,18 @@ namespace GameRes.Formats.Liar
|
||||
int m_width;
|
||||
int m_height;
|
||||
int m_bpp;
|
||||
int m_flags;
|
||||
|
||||
public byte[] Data { get { return m_image; } }
|
||||
public PixelFormat Format { get; private set; }
|
||||
|
||||
public Reader (Stream file, ImageMetaData info)
|
||||
public Reader (Stream file, LimMetaData info)
|
||||
{
|
||||
m_input = new ArcView.Reader (file);
|
||||
m_width = (int)info.Width;
|
||||
m_height = (int)info.Height;
|
||||
m_bpp = info.BPP;
|
||||
m_flags = info.Flags;
|
||||
if (32 == m_bpp)
|
||||
Format = PixelFormats.Bgra32;
|
||||
else if (16 == m_bpp)
|
||||
@ -106,10 +111,32 @@ namespace GameRes.Formats.Liar
|
||||
|
||||
public void Unpack ()
|
||||
{
|
||||
m_input.BaseStream.Position = 0x10;
|
||||
if (32 == m_bpp)
|
||||
{
|
||||
Unpack32bpp();
|
||||
}
|
||||
else
|
||||
Unpack16bpp();
|
||||
{
|
||||
if (0 != (m_flags & 0x10))
|
||||
{
|
||||
if (0 != (m_flags & 0xE0))
|
||||
Unpack16bpp();
|
||||
else
|
||||
m_input.Read (m_image, 0, m_image.Length);
|
||||
}
|
||||
if (0 != (m_flags & 0x100))
|
||||
{
|
||||
if (0 != (m_flags & 0xE00))
|
||||
{
|
||||
m_output = null;
|
||||
UnpackChannel (3);
|
||||
}
|
||||
else
|
||||
m_output = m_input.ReadBytes (m_width * m_height);
|
||||
ApplyAlpha (m_output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Unpack32bpp ()
|
||||
@ -196,24 +223,23 @@ namespace GameRes.Formats.Liar
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_input.BaseStream.Position < m_input.BaseStream.Length)
|
||||
}
|
||||
|
||||
void ApplyAlpha (byte[] alpha)
|
||||
{
|
||||
var pixels = new byte[m_width*m_height*4];
|
||||
int alpha_src = 0;
|
||||
int dst = 0;
|
||||
for (int i = 0; i < m_image.Length; i += 2)
|
||||
{
|
||||
m_output = null;
|
||||
UnpackChannel (3);
|
||||
var pixels = new byte[m_width*m_height*4];
|
||||
int alpha_src = 0;
|
||||
dst = 0;
|
||||
for (int i = 0; i < m_image.Length; i += 2)
|
||||
{
|
||||
int color = LittleEndian.ToUInt16 (m_image, i);
|
||||
pixels[dst++] = (byte)((color & 0x001F) * 0xFF / 0x1F);
|
||||
pixels[dst++] = (byte)((color & 0x07E0) * 0xFF / 0x7E0);
|
||||
pixels[dst++] = (byte)((color & 0xF800) * 0xFF / 0xF800);
|
||||
pixels[dst++] = (byte)~m_output[alpha_src++];
|
||||
}
|
||||
m_image = pixels;
|
||||
Format = PixelFormats.Bgra32;
|
||||
int color = LittleEndian.ToUInt16 (m_image, i);
|
||||
pixels[dst++] = (byte)((color & 0x001F) * 0xFF / 0x1F);
|
||||
pixels[dst++] = (byte)((color & 0x07E0) * 0xFF / 0x7E0);
|
||||
pixels[dst++] = (byte)((color & 0xF800) * 0xFF / 0xF800);
|
||||
pixels[dst++] = (byte)~alpha[alpha_src++];
|
||||
}
|
||||
m_image = pixels;
|
||||
Format = PixelFormats.Bgra32;
|
||||
}
|
||||
|
||||
void UnpackChannel (int card)
|
||||
@ -267,7 +293,7 @@ namespace GameRes.Formats.Liar
|
||||
count += 2;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (dst + 1 >= m_output.Length)
|
||||
if (dst >= m_output.Length)
|
||||
return;
|
||||
m_output[dst++] = m_index[index];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user