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