(TPGF): support 8bb images.

This commit is contained in:
morkt 2018-07-06 15:40:09 +04:00
parent 3866351fd0
commit 3afecbb9a4

View File

@ -30,6 +30,8 @@ using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using GameRes.Utility; using GameRes.Utility;
// [991218][Types] Ichou no Mau Koro 2
namespace GameRes.Formats.Types namespace GameRes.Formats.Types
{ {
[Export(typeof(ImageFormat))] [Export(typeof(ImageFormat))]
@ -75,6 +77,7 @@ namespace GameRes.Formats.Types
byte[] m_output; byte[] m_output;
ImageMetaData m_info; ImageMetaData m_info;
int m_stride; int m_stride;
byte[] m_scanline;
public byte[] Data { get { return m_output; } } public byte[] Data { get { return m_output; } }
public PixelFormat Format { get; private set; } public PixelFormat Format { get; private set; }
@ -82,37 +85,102 @@ namespace GameRes.Formats.Types
public TpgfReader (IBinaryStream input, ImageMetaData info) public TpgfReader (IBinaryStream input, ImageMetaData info)
{ {
if (8 == info.BPP)
throw new NotImplementedException();
m_input = new BitStreamEx (input.AsStream, true); m_input = new BitStreamEx (input.AsStream, true);
m_info = info; m_info = info;
m_stride = (int)m_info.Height * (info.BPP + 7) / 8; int bpp = m_info.BPP;
m_output = new byte[m_stride * (int)m_info.Width]; if (24 == bpp)
Format = PixelFormats.Bgr24; bpp = 32;
m_stride = (int)m_info.Width * (bpp / 8);
m_output = new byte[m_stride * (int)m_info.Height];
m_scanline = new byte[m_info.Width];
} }
public byte[] Unpack () public byte[] Unpack ()
{ {
m_input.Reset(); m_input.Reset();
m_input.Input.Position = 13; m_input.Input.Position = 13;
var scanline = new byte[m_info.Width]; if (8 == m_info.BPP)
{
Unpack8bpp (m_output);
Format = PixelFormats.Gray8;
return m_output; // alpha channel ignored for 8bpp bitmaps
}
else
{
Unpack24bpp (m_output);
Format = PixelFormats.Bgr32;
}
if (m_input.Input.ReadByte() == 1) // alpha data
{
var header = new byte[13];
m_input.Input.Read (header, 0, 13);
if (header.AsciiEqual (4, "TPGF"))
{
uint width = BigEndian.ToUInt16 (header, 8);
uint height = BigEndian.ToUInt16 (header, 10);
int bpp = header[12];
if (width == m_info.Width && height == m_info.Height && bpp == 8)
{
m_input.Reset();
UnpackAlpha (m_output);
Format = PixelFormats.Bgra32;
}
}
}
return m_output;
}
void Unpack24bpp (byte[] output)
{
int dst_line = 0; int dst_line = 0;
for (uint y = 0; y < m_info.Height; ++y) for (uint y = 0; y < m_info.Height; ++y)
{ {
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
{ {
ReadScanLine (scanline); ReadScanLine (m_scanline);
TransformLine (scanline); TransformLine (m_scanline);
int dst = dst_line + i; int dst = dst_line + i;
for (uint x = 0; x < m_info.Width; ++x) for (uint x = 0; x < m_info.Width; ++x)
{ {
m_output[dst] = scanline[x]; output[dst] = m_scanline[x];
dst += 3; dst += 4;
} }
} }
dst_line += m_stride; dst_line += m_stride;
} }
return m_output; }
void Unpack8bpp (byte[] output)
{
int width = (int)m_info.Width;
int dst = 0;
for (uint y = 0; y < m_info.Height; ++y)
{
ReadScanLine (m_scanline);
TransformLine (m_scanline);
for (int x = 0; x < width; ++x)
{
output[dst + x] = m_scanline[x];
}
dst += m_stride;
}
}
void UnpackAlpha (byte[] output)
{
int dst_line = 3;
for (uint y = 0; y < m_info.Height; ++y)
{
ReadScanLine (m_scanline);
TransformLine (m_scanline);
int dst = dst_line;
for (uint x = 0; x < m_info.Width; ++x)
{
output[dst] = (byte)~m_scanline[x];
dst += 4;
}
dst_line += m_stride;
}
} }
void ReadScanLine (byte[] line) void ReadScanLine (byte[] line)
@ -145,10 +213,9 @@ namespace GameRes.Formats.Types
void TransformLine (byte[] line) void TransformLine (byte[] line)
{ {
var tmp = line.Clone() as byte[];
for (int i = 1; i < line.Length; ++i) for (int i = 1; i < line.Length; ++i)
{ {
byte a = tmp[i]; byte a = line[i];
byte b = line[i-1]; byte b = line[i-1];
line[i] = TransformMap[a, b]; line[i] = TransformMap[a, b];
} }
@ -164,7 +231,7 @@ namespace GameRes.Formats.Types
{ {
int v; int v;
if (j >= 128) if (j >= 128)
v = -1 - j; v = (-1 - j) & 0xFF;
else else
v = j; v = j;
if (2 * v < i) if (2 * v < i)