(LimFormat): refined 16bpp images support.

This commit is contained in:
morkt 2016-04-25 18:00:02 +04:00
parent 3711e28d79
commit 2c82b05afa

View File

@ -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];
} }