(ImageFormat.ReadPalette): new static methods.

Generalized image palette deserializations.
This commit is contained in:
morkt
2017-01-14 16:27:11 +04:00
parent 832a1a3ff0
commit 13cf289bae
25 changed files with 87 additions and 331 deletions

View File

@@ -117,29 +117,12 @@ namespace GameRes.Formats.AZSys
m_input = input; m_input = input;
} }
public BitmapPalette ReadPalette ()
{
var palette_data = new byte[0x400];
if (0x400 != m_input.Read (palette_data, 0, 0x400))
throw new InvalidFormatException();
var palette = new Color[0x100];
for (int i = 0; i < palette.Length; ++i)
{
int src = i * 4;
byte b = palette_data[src++];
byte g = palette_data[src++];
byte r = palette_data[src++];
palette[i] = Color.FromRgb (r, g, b);
}
return new BitmapPalette (palette);
}
public void Unpack () public void Unpack ()
{ {
if (m_info.HasPalette) if (m_info.HasPalette)
{ {
m_input.Position = m_info.SeparateChannels ? 0x1E : 0x0E; m_input.Position = m_info.SeparateChannels ? 0x1E : 0x0E;
Palette = ReadPalette(); Palette = ImageFormat.ReadPalette (m_input);
} }
if (!m_info.SeparateChannels) if (!m_info.SeparateChannels)
{ {

View File

@@ -115,7 +115,7 @@ namespace GameRes.Formats.Abogado
if (8 == m_info.BPP) if (8 == m_info.BPP)
{ {
m_input.Position = m_info.PaletteOffset; m_input.Position = m_info.PaletteOffset;
ReadPalette(); Palette = ImageFormat.ReadPalette (m_input.AsStream);
} }
m_bits.Input.Position = m_info.DataOffset; m_bits.Input.Position = m_info.DataOffset;
ResetDict(); ResetDict();
@@ -181,20 +181,6 @@ namespace GameRes.Formats.Abogado
m_pixel_size = 4; m_pixel_size = 4;
} }
void ReadPalette ()
{
var palette_data = m_input.ReadBytes (0x400);
if (palette_data.Length != 0x400)
throw new EndOfStreamException();
var palette = new Color[0x100];
for (int i = 0; i < 0x100; ++i)
{
int c = i * 4;
palette[i] = Color.FromRgb (palette_data[c+2], palette_data[c+1], palette_data[c]);
}
Palette = new BitmapPalette (palette);
}
void UnpackChannel (int dst) void UnpackChannel (int dst)
{ {
m_output[dst] = (byte)m_bits.GetBits (8); m_output[dst] = (byte)m_bits.GetBits (8);

View File

@@ -244,16 +244,7 @@ namespace GameRes.Formats.Bishop
BitmapPalette ReadPalette () BitmapPalette ReadPalette ()
{ {
m_input.Position = m_info.PaletteOffset; m_input.Position = m_info.PaletteOffset;
var palette_data = new byte[0x400]; return ImageFormat.ReadPalette (m_input.AsStream);
if (palette_data.Length != m_input.Read (palette_data, 0, palette_data.Length))
throw new InvalidFormatException();
var palette = new Color[0x100];
for (int i = 0; i < palette.Length; ++i)
{
int c = i * 4;
palette[i] = Color.FromRgb (palette_data[c+2], palette_data[c+1], palette_data[c]);
}
return new BitmapPalette (palette);
} }
#region IDisposable Members #region IDisposable Members

View File

@@ -260,7 +260,7 @@ namespace GameRes.Formats.BlackCyc
if (8 == bpp) if (8 == bpp)
{ {
int colors = Math.Min (header.ToInt32 (0x2E), 0x100); int colors = Math.Min (header.ToInt32 (0x2E), 0x100);
palette = DwqBmpReader.ReadPalette (file.AsStream, colors); palette = ImageFormat.ReadPalette (file.AsStream, colors);
} }
int pixel_size = bpp / 8; int pixel_size = bpp / 8;
int stride = ((int)info.Width * pixel_size + 3) & ~3; int stride = ((int)info.Width * pixel_size + 3) & ~3;
@@ -324,30 +324,13 @@ namespace GameRes.Formats.BlackCyc
int colors = Math.Min (LittleEndian.ToInt32 (header, 0x2E), 0x100); int colors = Math.Min (LittleEndian.ToInt32 (header, 0x2E), 0x100);
if (0 == colors) if (0 == colors)
colors = 0x100; colors = 0x100;
Palette = ReadPalette (m_input, colors); Palette = ImageFormat.ReadPalette (m_input, colors);
} }
uint data_position = LittleEndian.ToUInt32 (header, 0xA); uint data_position = LittleEndian.ToUInt32 (header, 0xA);
m_input.Position = data_position; m_input.Position = data_position;
m_pixels = new byte[Stride*m_height]; m_pixels = new byte[Stride*m_height];
} }
public static BitmapPalette ReadPalette (Stream input, int colors)
{
int palette_size = colors * 4;
var palette_data = new byte[palette_size];
if (palette_size != input.Read (palette_data, 0, palette_size))
throw new InvalidFormatException();
var palette = new Color[colors];
for (int i = 0; i < palette.Length; ++i)
{
byte r = palette_data[i*4+2];
byte g = palette_data[i*4+1];
byte b = palette_data[i*4];
palette[i] = Color.FromRgb (r, g, b);
}
return new BitmapPalette (palette);
}
public void Unpack () // sub_408990 public void Unpack () // sub_408990
{ {
var prev_line = new byte[Stride]; var prev_line = new byte[Stride];

View File

@@ -77,7 +77,7 @@ namespace GameRes.Formats.EmonEngine
stream.Position = meta.DataOffset; stream.Position = meta.DataOffset;
BitmapPalette palette = null; BitmapPalette palette = null;
if (meta.Colors != 0) if (meta.Colors != 0)
palette = ReadPalette (stream.AsStream, Math.Max (meta.Colors, 3)); palette = ReadPalette (stream.AsStream, Math.Max (meta.Colors, 3), PaletteFormat.RgbX);
var pixels = new byte[meta.Stride * (int)info.Height]; var pixels = new byte[meta.Stride * (int)info.Height];
if (meta.LzssFrameSize != 0) if (meta.LzssFrameSize != 0)
{ {
@@ -107,22 +107,6 @@ namespace GameRes.Formats.EmonEngine
return ImageData.CreateFlipped (info, format, palette, pixels, meta.Stride); return ImageData.CreateFlipped (info, format, palette, pixels, meta.Stride);
} }
BitmapPalette ReadPalette (Stream input, int colors)
{
int palette_size = colors * 4;
var palette_data = new byte[palette_size];
if (palette_size != input.Read (palette_data, 0, palette_size))
throw new InvalidFormatException();
var palette = new Color[colors];
int src = 0;
for (int i = 0; i < palette.Length; ++i)
{
palette[i] = Color.FromRgb (palette_data[src], palette_data[src+1], palette_data[src+2]);
src += 4;
}
return new BitmapPalette (palette);
}
public override void Write (Stream file, ImageData image) public override void Write (Stream file, ImageData image)
{ {
throw new System.NotImplementedException ("EmFormat.Write not implemented"); throw new System.NotImplementedException ("EmFormat.Write not implemented");

View File

@@ -425,6 +425,9 @@ namespace GameRes.Formats.Entis
throw new InvalidFormatException(); throw new InvalidFormatException();
DecodeType2Image (context); DecodeType2Image (context);
return; return;
case 4:
DecodeType4Image (context);
return;
case 8: case 8:
if (nBitCount != 8) if (nBitCount != 8)
throw new InvalidFormatException(); throw new InvalidFormatException();
@@ -589,6 +592,11 @@ namespace GameRes.Formats.Entis
} }
} }
private void DecodeType4Image (RLEDecodeContext context)
{
throw new NotImplementedException ("Arithmetic compression not implemented");
}
private void DecodeLossyImage (HuffmanDecodeContext context) private void DecodeLossyImage (HuffmanDecodeContext context)
{ {
context.FlushBuffer(); context.FlushBuffer();

View File

@@ -246,17 +246,10 @@ namespace GameRes.Formats.Entis
internal static Color[] ReadPalette (Stream input, int palette_length) internal static Color[] ReadPalette (Stream input, int palette_length)
{ {
var palette_data = new byte[0x400]; int colors = palette_length / 4;
if (palette_length > palette_data.Length) if (colors <= 0 || colors > 0x100)
throw new InvalidFormatException(); throw new InvalidFormatException();
if (palette_length != input.Read (palette_data, 0, palette_length)) return ImageFormat.ReadColorMap (input, colors);
throw new InvalidFormatException();
var colors = new Color[256];
for (int i = 0; i < 256; ++i)
{
colors[i] = Color.FromRgb (palette_data[i*4+2], palette_data[i*4+1], palette_data[i*4]);
}
return colors;
} }
internal EriReader ReadImageData (IBinaryStream stream, EriMetaData meta) internal EriReader ReadImageData (IBinaryStream stream, EriMetaData meta)

View File

@@ -82,25 +82,12 @@ namespace GameRes.Formats.Eushully
if (8 == info.SourceBPP) if (8 == info.SourceBPP)
{ {
reader.Read (header, 0, 0x18); // skip rest of the header reader.Read (header, 0, 0x18); // skip rest of the header
info.Palette = ReadPalette (reader.BaseStream); info.Palette = ReadColorMap (reader.BaseStream);
} }
return info; return info;
} }
} }
static Color[] ReadPalette (Stream input)
{
var palette_data = new byte[0x400];
if (0x400 != input.Read (palette_data, 0, 0x400))
throw new EndOfStreamException();
var palette = new Color[0x100];
for (int i = 0; i < palette.Length; ++i)
{
palette[i] = Color.FromRgb (palette_data[i*4+2], palette_data[i*4+1], palette_data[i*4]);
}
return palette;
}
public override ImageData Read (IBinaryStream stream, ImageMetaData info) public override ImageData Read (IBinaryStream stream, ImageMetaData info)
{ {
using (var reader = new AgfReader (stream, (AgfMetaData)info)) using (var reader = new AgfReader (stream, (AgfMetaData)info))

View File

@@ -185,7 +185,7 @@ namespace GameRes.Formats.ExHibit
{ {
m_input.Position = 0x24; m_input.Position = 0x24;
if (0 != m_info.PaletteSize) if (0 != m_info.PaletteSize)
Palette = ReadPalette (m_info.PaletteSize); Palette = ImageFormat.ReadPalette (m_input, m_info.PaletteSize);
var packed = new byte[m_info.DataSize]; var packed = new byte[m_info.DataSize];
if (packed.Length != m_input.Read (packed, 0, packed.Length)) if (packed.Length != m_input.Read (packed, 0, packed.Length))
@@ -267,20 +267,6 @@ namespace GameRes.Formats.ExHibit
} }
} }
BitmapPalette ReadPalette (int colors)
{
var palette_data = new byte[colors*4];
if (palette_data.Length != m_input.Read (palette_data, 0, palette_data.Length))
throw new InvalidFormatException();
var palette = new Color[colors];
for (int i = 0; i < palette.Length; ++i)
{
int c = i * 4;
palette[i] = Color.FromRgb (palette_data[c+2], palette_data[c+1], palette_data[c]);
}
return new BitmapPalette (palette);
}
void ReadAlpha () void ReadAlpha ()
{ {
int alpha_stride = (m_width + 3) & ~3; int alpha_stride = (m_width + 3) & ~3;

View File

@@ -69,7 +69,7 @@ namespace GameRes.Formats.FC01
BitmapPalette palette = null; BitmapPalette palette = null;
if (8 == bpp) if (8 == bpp)
{ {
palette = ReadPalette (file, index_offset); palette = ImageFormat.ReadPalette (file, index_offset);
index_offset += 0x400; index_offset += 0x400;
} }
string base_name = Path.GetFileNameWithoutExtension (file.Name); string base_name = Path.GetFileNameWithoutExtension (file.Name);
@@ -112,19 +112,6 @@ namespace GameRes.Formats.FC01
} }
} }
BitmapPalette ReadPalette (ArcView file, uint offset)
{
var palette = file.View.ReadBytes (offset, 0x400);
int src = 0;
var colors = new Color[0x100];
for (int i = 0; i < 0x100; ++i)
{
colors[i] = Color.FromRgb (palette[src+2], palette[src+1], palette[src]);
src += 4;
}
return new BitmapPalette (colors);
}
public override ResourceOptions GetDefaultOptions () public override ResourceOptions GetDefaultOptions ()
{ {
return new McgOptions { Key = Settings.Default.MCGLastKey }; return new McgOptions { Key = Settings.Default.MCGLastKey };

View File

@@ -92,20 +92,6 @@ namespace GameRes.Formats.FC01
} }
} }
BitmapPalette ReadPalette (Stream input)
{
var palette_data = new byte[0x400];
if (palette_data.Length != input.Read (palette_data, 0, palette_data.Length))
throw new InvalidFormatException();
var palette = new Color[0x100];
for (int i = 0; i < palette.Length; ++i)
{
int c = i * 4;
palette[i] = Color.FromRgb (palette_data[c+2], palette_data[c+1], palette_data[c]);
}
return new BitmapPalette (palette);
}
public override void Write (Stream file, ImageData image) public override void Write (Stream file, ImageData image)
{ {
throw new System.NotImplementedException ("ClmFormat.Write not implemented"); throw new System.NotImplementedException ("ClmFormat.Write not implemented");

View File

@@ -67,7 +67,7 @@ namespace GameRes.Formats.Gpk2
if (8 == meta.BPP && meta.DataOffset != 0x40) if (8 == meta.BPP && meta.DataOffset != 0x40)
{ {
stream.Position = 0x40; stream.Position = 0x40;
palette = ReadPalette (stream.AsStream, meta.DataOffset - 0x40); palette = ReadPalette (stream, meta.DataOffset - 0x40);
} }
stream.Position = meta.DataOffset; stream.Position = meta.DataOffset;
@@ -113,11 +113,11 @@ namespace GameRes.Formats.Gpk2
return ImageData.CreateFlipped (info, format, palette, pixels, stride); return ImageData.CreateFlipped (info, format, palette, pixels, stride);
} }
BitmapPalette ReadPalette (Stream input, int palette_size) BitmapPalette ReadPalette (IBinaryStream input, int palette_size)
{ {
palette_size = Math.Min (0x400, palette_size); palette_size = Math.Min (0x400, palette_size);
var palette_data = new byte[palette_size]; var palette_data = input.ReadBytes (palette_size);
if (palette_data.Length != input.Read (palette_data, 0, palette_data.Length)) if (palette_data.Length != palette_size)
throw new EndOfStreamException(); throw new EndOfStreamException();
int color_size = palette_size / 0x100; int color_size = palette_size / 0x100;
var palette = new Color[0x100]; var palette = new Color[0x100];

View File

@@ -118,17 +118,5 @@ namespace GameRes.Formats.Gs
{ {
throw new NotImplementedException ("PicFormat.Write not implemented"); throw new NotImplementedException ("PicFormat.Write not implemented");
} }
private static BitmapPalette ReadPalette (Stream input)
{
var colors = new byte[0x400];
if (colors.Length != input.Read (colors, 0, colors.Length))
throw new InvalidFormatException();
var color_data = new Color[0x100];
int n = 0;
for (int i = 0; i < 0x400; i += 4)
color_data[n++] = Color.FromRgb (colors[i+2], colors[i+1], colors[i]);
return new BitmapPalette (color_data);
}
} }
} }

View File

@@ -179,17 +179,8 @@ namespace GameRes.Formats.Adobe
void ReadPalette (int palette_size) void ReadPalette (int palette_size)
{ {
var palette_data = m_input.ReadBytes (palette_size); int colors = Math.Min (0x100, palette_size/3);
if (palette_data.Length != palette_size) Palette = ImageFormat.ReadPalette (m_input.AsStream, colors, PaletteFormat.Rgb);
throw new EndOfStreamException();
int colors = Math.Min (256, palette_size/3);
var palette = new Color[colors];
for (int i = 0; i < colors; ++i)
{
int c = i * 3;
palette[i] = Color.FromRgb (palette_data[c], palette_data[c+1], palette_data[c+2]);
}
Palette = new BitmapPalette (palette);
} }
byte[] UnpackRLE () byte[] UnpackRLE ()

View File

@@ -183,22 +183,7 @@ namespace GameRes.Formats.Seraphim
public BitmapPalette ReadPalette (int colors) public BitmapPalette ReadPalette (int colors)
{ {
int palette_size = colors * 3; return ImageFormat.ReadPalette (m_input, Math.Min (colors, 0x100), PaletteFormat.Rgb);
var palette_data = new byte[Math.Max (palette_size, 0x300)];
if (palette_size != m_input.Read (palette_data, 0, palette_size))
throw new InvalidFormatException();
var palette = new Color[0x100];
if (colors > 0x100)
colors = 0x100;
int src = 0;
for (int i = 0; i < palette.Length; ++i)
{
byte r = palette_data[src++];
byte g = palette_data[src++];
byte b = palette_data[src++];
palette[i] = Color.FromRgb (r, g, b);
}
return new BitmapPalette (palette);
} }
public void UnpackCb () public void UnpackCb ()

View File

@@ -76,7 +76,7 @@ namespace GameRes.Formats.BaseUnit
else if (8 == info.BPP) else if (8 == info.BPP)
{ {
stream.Position = 0x20; stream.Position = 0x20;
var palette = ReadPalette (stream.AsStream); var palette = ReadPalette (stream.AsStream, 0x100, PaletteFormat.RgbX);
var pixels = new byte[info.Width * info.Height]; var pixels = new byte[info.Width * info.Height];
if (pixels.Length != stream.Read (pixels, 0, pixels.Length)) if (pixels.Length != stream.Read (pixels, 0, pixels.Length))
throw new EndOfStreamException(); throw new EndOfStreamException();
@@ -90,19 +90,5 @@ namespace GameRes.Formats.BaseUnit
{ {
throw new System.NotImplementedException ("IesFormat.Write not implemented"); throw new System.NotImplementedException ("IesFormat.Write not implemented");
} }
BitmapPalette ReadPalette (Stream input)
{
var palette_data = new byte[0x400];
if (palette_data.Length != input.Read (palette_data, 0, palette_data.Length))
throw new EndOfStreamException();
var palette = new Color[0x100];
for (int i = 0; i < 0x100; ++i)
{
int c = i * 4;
palette[i] = Color.FromRgb (palette_data[c], palette_data[c+1], palette_data[c+2]);
}
return new BitmapPalette (palette);
}
} }
} }

View File

@@ -113,7 +113,7 @@ namespace GameRes.Formats.Ivory
} }
} }
input.Position = 0x18 + meta.Size2 + meta.Size3; input.Position = 0x18 + meta.Size2 + meta.Size3;
var palette = ReadPalette (input.AsStream, meta.Colors); var palette = ReadPalette (input.AsStream, Math.Min (0x100, meta.Colors), PaletteFormat.Rgb);
return ImageData.Create (info, PixelFormats.Indexed8, palette, pixels); return ImageData.Create (info, PixelFormats.Indexed8, palette, pixels);
} }
@@ -122,26 +122,6 @@ namespace GameRes.Formats.Ivory
0, 2, 4, 8, 0, 2, 0, 2, 4, 0, 2, 4, 0, 2, 4, 0, 0, 2, 4, 8, 0, 2, 0, 2, 4, 0, 2, 4, 0, 2, 4, 0,
}; };
BitmapPalette ReadPalette (Stream input, int colors)
{
int palette_size = colors * 3;
var palette_data = new byte[Math.Max (palette_size, 0x300)];
if (palette_size != input.Read (palette_data, 0, palette_size))
throw new EndOfStreamException();
var palette = new Color[0x100];
if (colors > 0x100)
colors = 0x100;
int src = 0;
for (int i = 0; i < palette.Length; ++i)
{
byte r = palette_data[src++];
byte g = palette_data[src++];
byte b = palette_data[src++];
palette[i] = Color.FromRgb (r, g, b);
}
return new BitmapPalette (palette);
}
public override void Write (Stream file, ImageData image) public override void Write (Stream file, ImageData image)
{ {
throw new System.NotImplementedException ("MmdFormat.Write not implemented"); throw new System.NotImplementedException ("MmdFormat.Write not implemented");

View File

@@ -239,7 +239,7 @@ namespace GameRes.Formats.Ivory
m_output = new byte[m_width * m_height]; m_output = new byte[m_width * m_height];
Format = PixelFormats.Indexed8; Format = PixelFormats.Indexed8;
Palette = new BitmapPalette (ReadPalette()); Palette = ImageFormat.ReadPalette (m_input.AsStream);
var index = new int[m_height]; var index = new int[m_height];
for (int i = 0; i < m_height; ++i) for (int i = 0; i < m_height; ++i)
index[i] = m_input.ReadInt32(); index[i] = m_input.ReadInt32();
@@ -278,7 +278,7 @@ namespace GameRes.Formats.Ivory
m_output = new byte[m_stride * m_height]; m_output = new byte[m_stride * m_height];
Format = PixelFormats.Bgra32; Format = PixelFormats.Bgra32;
var palette = ReadPalette(); var palette = ImageFormat.ReadColorMap (m_input.AsStream);
var index = new int[m_height]; var index = new int[m_height];
for (int i = 0; i < m_height; ++i) for (int i = 0; i < m_height; ++i)
index[i] = m_input.ReadInt32(); index[i] = m_input.ReadInt32();
@@ -343,20 +343,6 @@ namespace GameRes.Formats.Ivory
} }
} }
Color[] ReadPalette ()
{
var palette_data = m_input.ReadBytes (0x400);
if (palette_data.Length != 0x400)
throw new EndOfStreamException();
var palette = new Color[0x100];
for (int i = 0; i < 0x100; ++i)
{
int c = i * 4;
palette[i] = Color.FromRgb (palette_data[c+2], palette_data[c+1], palette_data[c]);
}
return palette;
}
#region IDisposable Members #region IDisposable Members
public void Dispose () public void Dispose ()
{ {

View File

@@ -63,7 +63,7 @@ namespace GameRes.Formats.Leaf
stream.Position = 12; stream.Position = 12;
BitmapPalette palette = null; BitmapPalette palette = null;
if (8 == info.BPP) if (8 == info.BPP)
palette = ReadPalette (stream.AsStream); palette = ReadPalette (stream.AsStream, 0x100, PaletteFormat.RgbX);
if (pixels.Length != stream.Read (pixels, 0, pixels.Length)) if (pixels.Length != stream.Read (pixels, 0, pixels.Length))
throw new EndOfStreamException(); throw new EndOfStreamException();
PixelFormat format = 24 == info.BPP ? PixelFormats.Bgr24 PixelFormat format = 24 == info.BPP ? PixelFormats.Bgr24
@@ -76,19 +76,5 @@ namespace GameRes.Formats.Leaf
{ {
throw new System.NotImplementedException ("LgfFormat.Write not implemented"); throw new System.NotImplementedException ("LgfFormat.Write not implemented");
} }
BitmapPalette ReadPalette (Stream input)
{
var palette_data = new byte[0x400];
if (palette_data.Length != input.Read (palette_data, 0, palette_data.Length))
throw new EndOfStreamException();
var palette = new Color[0x100];
for (int i = 0; i < 0x100; ++i)
{
int c = i * 4;
palette[i] = Color.FromRgb (palette_data[c], palette_data[c+1], palette_data[c+2]);
}
return new BitmapPalette (palette);
}
} }
} }

View File

@@ -236,7 +236,7 @@ namespace GameRes.Formats.LiveMaker
if (frame.BPP <= 0) if (frame.BPP <= 0)
throw new InvalidFormatException(); throw new InvalidFormatException();
if (frame.BPP <= 8) if (frame.BPP <= 8)
frame.Palette = ReadPalette (1 << frame.BPP); frame.Palette = ImageFormat.ReadColorMap (m_input.AsStream, 1 << frame.BPP);
frame.Stride = (frame.Width * frame.BPP + 7) / 8; frame.Stride = (frame.Width * frame.BPP + 7) / 8;
frame.AlphaStride = (frame.Width + 3) & ~3; frame.AlphaStride = (frame.Width + 3) & ~3;
if (frame.BPP >= 8) if (frame.BPP >= 8)
@@ -525,20 +525,6 @@ namespace GameRes.Formats.LiveMaker
} }
} }
Color[] ReadPalette (int colors)
{
var palette_data = m_input.ReadBytes (4 * colors);
if (palette_data.Length != 4 * colors)
throw new EndOfStreamException();
var palette = new Color[colors];
for (int i = 0; i < colors; ++i)
{
int c = i * 4;
palette[i] = Color.FromRgb (palette_data[c+2], palette_data[c+1], palette_data[c]);
}
return palette;
}
void ShuffleBlocks (int[] refs, int count) void ShuffleBlocks (int[] refs, int count)
{ {
var copy = refs.Clone() as int[]; var copy = refs.Clone() as int[];

View File

@@ -123,7 +123,7 @@ namespace GameRes.Formats.MAI
if (info.Colors > 0) if (info.Colors > 0)
{ {
m_input.Position = 0x20; m_input.Position = 0x20;
Palette = RleDecoder.ReadPalette (m_input, info.Colors, 3); Palette = ImageFormat.ReadPalette (m_input, info.Colors, PaletteFormat.Bgr);
} }
m_input.Position = info.DataOffset; m_input.Position = info.DataOffset;
int size = info.IsCompressed ? m_width*m_height*m_pixel_size : (int)info.DataLength; int size = info.IsCompressed ? m_width*m_height*m_pixel_size : (int)info.DataLength;
@@ -240,7 +240,7 @@ namespace GameRes.Formats.MAI
{ {
m_input.Position = m_info.DataOffset; m_input.Position = m_info.DataOffset;
if (m_info.Colors > 0) if (m_info.Colors > 0)
Palette = RleDecoder.ReadPalette (m_input, m_info.Colors, 3); Palette = ImageFormat.ReadPalette (m_input, m_info.Colors, PaletteFormat.Bgr);
if (m_info.IsCompressed) if (m_info.IsCompressed)
RleDecoder.Unpack (m_input, (int)m_info.DataLength, m_output, m_pixel_size); RleDecoder.Unpack (m_input, (int)m_info.DataLength, m_output, m_pixel_size);
else else
@@ -324,7 +324,7 @@ namespace GameRes.Formats.MAI
{ {
var meta = (CmMetaData)info; var meta = (CmMetaData)info;
stream.Position = meta.DataOffset; stream.Position = meta.DataOffset;
var palette = RleDecoder.ReadPalette (stream.AsStream, 0x100, 4); var palette = ReadPalette (stream.AsStream, 0x100, PaletteFormat.BgrX);
var pixels = new byte[info.Width*info.Height]; var pixels = new byte[info.Width*info.Height];
if (meta.IsCompressed) if (meta.IsCompressed)
@@ -341,20 +341,6 @@ namespace GameRes.Formats.MAI
internal class RleDecoder internal class RleDecoder
{ {
public static BitmapPalette ReadPalette (Stream input, int colors, int color_size)
{
var palette_data = new byte[colors*color_size];
if (palette_data.Length != input.Read (palette_data, 0, palette_data.Length))
throw new InvalidFormatException();
var palette = new Color[colors];
for (int i = 0; i < palette.Length; ++i)
{
int c = i * color_size;
palette[i] = Color.FromRgb (palette_data[c+2], palette_data[c+1], palette_data[c]);
}
return new BitmapPalette (palette);
}
static public void Unpack (Stream input, int input_size, byte[] output, int pixel_size) static public void Unpack (Stream input, int input_size, byte[] output, int pixel_size)
{ {
int read = 0; int read = 0;

View File

@@ -117,20 +117,7 @@ namespace GameRes.Formats.Pajamas
m_height = (int)info.Height; m_height = (int)info.Height;
m_output = new byte[info.Width*info.Height*m_pixel_size]; m_output = new byte[info.Width*info.Height*m_pixel_size];
if (8 == info.BPP) if (8 == info.BPP)
ReadPalette(); Palette = ImageFormat.ReadPalette (m_input, 0x100, PaletteFormat.Bgr);
}
private void ReadPalette ()
{
var palette_data = new byte[0x300];
if (palette_data.Length != m_input.Read (palette_data, 0, palette_data.Length))
throw new InvalidFormatException();
var palette = new Color[0x100];
for (int i = 0; i < palette.Length; ++i)
{
palette[i] = Color.FromRgb (palette_data[i*3+2], palette_data[i*3+1], palette_data[i*3]);
}
Palette = new BitmapPalette (palette);
} }
public void Unpack () public void Unpack ()

View File

@@ -126,7 +126,7 @@ namespace GameRes.Formats.Vitamin
int input_size = m_info.InputSize - 0x20; int input_size = m_info.InputSize - 0x20;
if (m_info.HasPalette) if (m_info.HasPalette)
{ {
ReadPalette(); Palette = ImageFormat.ReadPalette (m_input.AsStream, 0x100, PaletteFormat.Rgb);
input_size -= 0x300; input_size -= 0x300;
} }
int x = 0; int x = 0;
@@ -188,20 +188,6 @@ namespace GameRes.Formats.Vitamin
} }
} }
void ReadPalette ()
{
var palette_data = m_input.ReadBytes (0x300);
if (palette_data.Length != 0x300)
throw new EndOfStreamException();
var palette = new Color[0x100];
for (int i = 0; i < 0x100; ++i)
{
int c = i * 3;
palette[i] = Color.FromRgb (palette_data[c], palette_data[c+1], palette_data[c+2]);
}
Palette = new BitmapPalette (palette);
}
#region IDisposable Members #region IDisposable Members
public void Dispose () public void Dispose ()
{ {

View File

@@ -69,20 +69,6 @@ namespace GameRes.Formats.Elf
} }
} }
public static BitmapPalette ReadPalette (Stream input)
{
var palette_data = new byte[0x400];
if (palette_data.Length != input.Read (palette_data, 0, palette_data.Length))
throw new InvalidFormatException();
var palette = new Color[0x100];
for (int i = 0; i < palette.Length; ++i)
{
int c = i * 4;
palette[i] = Color.FromRgb (palette_data[c+2], palette_data[c+1], palette_data[c]);
}
return new BitmapPalette (palette);
}
public override void Write (Stream file, ImageData image) public override void Write (Stream file, ImageData image)
{ {
throw new System.NotImplementedException ("Gp8Format.Write not implemented"); throw new System.NotImplementedException ("Gp8Format.Write not implemented");

View File

@@ -46,6 +46,17 @@ namespace GameRes
public override string Type { get { return "image"; } } public override string Type { get { return "image"; } }
} }
/// <summary>
/// Enumeration representing possible palette serialization formats.
/// </summary>
public enum PaletteFormat
{
Rgb = 1,
Bgr = 2,
RgbX = 5,
BgrX = 6,
}
public class ImageData public class ImageData
{ {
private BitmapSource m_bitmap; private BitmapSource m_bitmap;
@@ -171,5 +182,43 @@ namespace GameRes
public static ImageFormat Png { get { return s_PngFormat.Value; } } public static ImageFormat Png { get { return s_PngFormat.Value; } }
public static ImageFormat Bmp { get { return s_BmpFormat.Value; } } public static ImageFormat Bmp { get { return s_BmpFormat.Value; } }
public static ImageFormat Tga { get { return s_TgaFormat.Value; } } public static ImageFormat Tga { get { return s_TgaFormat.Value; } }
/// <summary>
/// Desereialize color map from <paramref name="input"/> stream, consisting of specified number of
/// <paramref name="colors"/> stored in specified <paramref name="format"/>.
/// Default number of colors is 256 and format is 4-byte BGRX (where X is an unsignificant byte).
/// </summary>
public static Color[] ReadColorMap (Stream input, int colors = 0x100, PaletteFormat format = PaletteFormat.BgrX)
{
int bpp = PaletteFormat.Rgb == format || PaletteFormat.Bgr == format ? 3 : 4;
var palette_data = new byte[bpp * colors];
if (palette_data.Length != input.Read (palette_data, 0, palette_data.Length))
throw new EndOfStreamException();
int src = 0;
var color_map = new Color[colors];
Func<int, Color> get_color;
if (PaletteFormat.Bgr == format || PaletteFormat.BgrX == format)
get_color = x => Color.FromRgb (palette_data[x+2], palette_data[x+1], palette_data[x]);
else
get_color = x => Color.FromRgb (palette_data[x], palette_data[x+1], palette_data[x+2]);
for (int i = 0; i < colors; ++i)
{
color_map[i] = get_color (src);
src += bpp;
}
return color_map;
}
public static BitmapPalette ReadPalette (Stream input, int colors = 0x100, PaletteFormat format = PaletteFormat.BgrX)
{
return new BitmapPalette (ReadColorMap (input, colors, format));
}
public static BitmapPalette ReadPalette (ArcView file, long offset, int colors = 0x100, PaletteFormat format = PaletteFormat.BgrX)
{
using (var input = file.CreateStream (offset, (uint)(4 * colors))) // largest possible size for palette
return ReadPalette (input, colors, format);
}
} }
} }