(Legacy): fixed FB images decoder.

This commit is contained in:
morkt
2018-12-19 03:35:32 +04:00
parent eb72b78b45
commit d75bc26cbc

View File

@@ -46,7 +46,7 @@ namespace GameRes.Formats.Akatombo
return new ImageMetaData { return new ImageMetaData {
Width = header.ToUInt16 (4), Width = header.ToUInt16 (4),
Height = header.ToUInt16 (6), Height = header.ToUInt16 (6),
BPP = header.ToUInt16 (2), BPP = header[2],
}; };
} }
@@ -54,7 +54,7 @@ namespace GameRes.Formats.Akatombo
{ {
var reader = new FbReader (file, info); var reader = new FbReader (file, info);
var pixels = reader.Unpack(); var pixels = reader.Unpack();
return ImageData.Create (info, reader.Format, null, pixels); return ImageData.CreateFlipped (info, reader.Format, null, pixels, reader.Stride);
} }
public override void Write (Stream file, ImageData image) public override void Write (Stream file, ImageData image)
@@ -67,17 +67,17 @@ namespace GameRes.Formats.Akatombo
{ {
IBinaryStream m_input; IBinaryStream m_input;
int m_width; int m_width;
int m_pixel_count;
byte[] m_output; byte[] m_output;
public PixelFormat Format { get; private set; } public PixelFormat Format { get; private set; }
public int Stride { get; private set; }
public FbReader (IBinaryStream input, ImageMetaData info) public FbReader (IBinaryStream input, ImageMetaData info)
{ {
m_input = input; m_input = input;
m_width = (int)info.Width; m_width = info.iWidth;
m_pixel_count = m_width * (int)info.Height; Stride = 4 * m_width;
m_output = new byte[m_pixel_count * 4]; m_output = new byte[Stride * info.iHeight];
Format = PixelFormats.Bgr32; Format = PixelFormats.Bgr32;
} }
@@ -87,8 +87,7 @@ namespace GameRes.Formats.Akatombo
{ {
m_input.Position = 8; m_input.Position = 8;
m_bits = 0x80000000; m_bits = 0x80000000;
int dst = 0; for (int dst = 0; dst < m_output.Length; dst += 4)
for (int i = 0; i < m_pixel_count; ++i)
{ {
int bit = GetNextBit(); int bit = GetNextBit();
if (0 == bit) if (0 == bit)
@@ -105,37 +104,36 @@ namespace GameRes.Formats.Akatombo
m_output[dst ] += ReadDiff(); m_output[dst ] += ReadDiff();
m_output[dst+1] += ReadDiff(); m_output[dst+1] += ReadDiff();
m_output[dst+2] += ReadDiff(); m_output[dst+2] += ReadDiff();
dst += 4;
} }
return m_output; return m_output;
} }
byte ReadDiff () byte ReadDiff ()
{ {
uint n = 1; int count = 1;
do while (GetNextBit() != 0)
{ {
n = Binary.RotR (n, 1); ++count;
} }
while (GetNextBit() != 0); int n = 1;
++n; while (count --> 0)
byte bit;
do
{ {
bit = (byte)GetNextBit(); n = (n << 1) | GetNextBit();
n = (n << 1) | bit;
} }
while (0 == bit);
return (byte)(-(n & 1) ^ ((n >> 1) - 1)); return (byte)(-(n & 1) ^ ((n >> 1) - 1));
} }
byte[] m_bits_buffer = new byte[4];
int GetNextBit () int GetNextBit ()
{ {
uint bit = m_bits >> 31; uint bit = m_bits >> 31;
m_bits <<= 1; m_bits <<= 1;
if (0 == m_bits) if (0 == m_bits)
{ {
m_bits = Binary.BigEndian (m_input.ReadUInt32()); if (0 == m_input.Read (m_bits_buffer, 0, 4))
throw new EndOfStreamException();
m_bits = BigEndian.ToUInt32 (m_bits_buffer, 0);
bit = m_bits >> 31; bit = m_bits >> 31;
m_bits = (m_bits << 1) | 1; m_bits = (m_bits << 1) | 1;
} }