(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;
}
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 ()
{
if (m_info.HasPalette)
{
m_input.Position = m_info.SeparateChannels ? 0x1E : 0x0E;
Palette = ReadPalette();
Palette = ImageFormat.ReadPalette (m_input);
}
if (!m_info.SeparateChannels)
{

View File

@ -115,7 +115,7 @@ namespace GameRes.Formats.Abogado
if (8 == m_info.BPP)
{
m_input.Position = m_info.PaletteOffset;
ReadPalette();
Palette = ImageFormat.ReadPalette (m_input.AsStream);
}
m_bits.Input.Position = m_info.DataOffset;
ResetDict();
@ -181,20 +181,6 @@ namespace GameRes.Formats.Abogado
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)
{
m_output[dst] = (byte)m_bits.GetBits (8);

View File

@ -244,16 +244,7 @@ namespace GameRes.Formats.Bishop
BitmapPalette ReadPalette ()
{
m_input.Position = m_info.PaletteOffset;
var palette_data = new byte[0x400];
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);
return ImageFormat.ReadPalette (m_input.AsStream);
}
#region IDisposable Members

View File

@ -260,7 +260,7 @@ namespace GameRes.Formats.BlackCyc
if (8 == bpp)
{
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 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);
if (0 == colors)
colors = 0x100;
Palette = ReadPalette (m_input, colors);
Palette = ImageFormat.ReadPalette (m_input, colors);
}
uint data_position = LittleEndian.ToUInt32 (header, 0xA);
m_input.Position = data_position;
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
{
var prev_line = new byte[Stride];

View File

@ -77,7 +77,7 @@ namespace GameRes.Formats.EmonEngine
stream.Position = meta.DataOffset;
BitmapPalette palette = null;
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];
if (meta.LzssFrameSize != 0)
{
@ -107,22 +107,6 @@ namespace GameRes.Formats.EmonEngine
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)
{
throw new System.NotImplementedException ("EmFormat.Write not implemented");

View File

@ -425,6 +425,9 @@ namespace GameRes.Formats.Entis
throw new InvalidFormatException();
DecodeType2Image (context);
return;
case 4:
DecodeType4Image (context);
return;
case 8:
if (nBitCount != 8)
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)
{
context.FlushBuffer();

View File

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

View File

@ -82,25 +82,12 @@ namespace GameRes.Formats.Eushully
if (8 == info.SourceBPP)
{
reader.Read (header, 0, 0x18); // skip rest of the header
info.Palette = ReadPalette (reader.BaseStream);
info.Palette = ReadColorMap (reader.BaseStream);
}
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)
{
using (var reader = new AgfReader (stream, (AgfMetaData)info))

View File

@ -185,7 +185,7 @@ namespace GameRes.Formats.ExHibit
{
m_input.Position = 0x24;
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];
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 ()
{
int alpha_stride = (m_width + 3) & ~3;

View File

@ -69,7 +69,7 @@ namespace GameRes.Formats.FC01
BitmapPalette palette = null;
if (8 == bpp)
{
palette = ReadPalette (file, index_offset);
palette = ImageFormat.ReadPalette (file, index_offset);
index_offset += 0x400;
}
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 ()
{
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)
{
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)
{
stream.Position = 0x40;
palette = ReadPalette (stream.AsStream, meta.DataOffset - 0x40);
palette = ReadPalette (stream, meta.DataOffset - 0x40);
}
stream.Position = meta.DataOffset;
@ -113,11 +113,11 @@ namespace GameRes.Formats.Gpk2
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);
var palette_data = new byte[palette_size];
if (palette_data.Length != input.Read (palette_data, 0, palette_data.Length))
var palette_data = input.ReadBytes (palette_size);
if (palette_data.Length != palette_size)
throw new EndOfStreamException();
int color_size = palette_size / 0x100;
var palette = new Color[0x100];

View File

@ -118,17 +118,5 @@ namespace GameRes.Formats.Gs
{
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)
{
var palette_data = m_input.ReadBytes (palette_size);
if (palette_data.Length != palette_size)
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);
int colors = Math.Min (0x100, palette_size/3);
Palette = ImageFormat.ReadPalette (m_input.AsStream, colors, PaletteFormat.Rgb);
}
byte[] UnpackRLE ()

View File

@ -183,22 +183,7 @@ namespace GameRes.Formats.Seraphim
public BitmapPalette ReadPalette (int colors)
{
int palette_size = colors * 3;
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);
return ImageFormat.ReadPalette (m_input, Math.Min (colors, 0x100), PaletteFormat.Rgb);
}
public void UnpackCb ()

View File

@ -76,7 +76,7 @@ namespace GameRes.Formats.BaseUnit
else if (8 == info.BPP)
{
stream.Position = 0x20;
var palette = ReadPalette (stream.AsStream);
var palette = ReadPalette (stream.AsStream, 0x100, PaletteFormat.RgbX);
var pixels = new byte[info.Width * info.Height];
if (pixels.Length != stream.Read (pixels, 0, pixels.Length))
throw new EndOfStreamException();
@ -90,19 +90,5 @@ namespace GameRes.Formats.BaseUnit
{
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;
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);
}
@ -122,26 +122,6 @@ namespace GameRes.Formats.Ivory
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)
{
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];
Format = PixelFormats.Indexed8;
Palette = new BitmapPalette (ReadPalette());
Palette = ImageFormat.ReadPalette (m_input.AsStream);
var index = new int[m_height];
for (int i = 0; i < m_height; ++i)
index[i] = m_input.ReadInt32();
@ -278,7 +278,7 @@ namespace GameRes.Formats.Ivory
m_output = new byte[m_stride * m_height];
Format = PixelFormats.Bgra32;
var palette = ReadPalette();
var palette = ImageFormat.ReadColorMap (m_input.AsStream);
var index = new int[m_height];
for (int i = 0; i < m_height; ++i)
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
public void Dispose ()
{

View File

@ -63,7 +63,7 @@ namespace GameRes.Formats.Leaf
stream.Position = 12;
BitmapPalette palette = null;
if (8 == info.BPP)
palette = ReadPalette (stream.AsStream);
palette = ReadPalette (stream.AsStream, 0x100, PaletteFormat.RgbX);
if (pixels.Length != stream.Read (pixels, 0, pixels.Length))
throw new EndOfStreamException();
PixelFormat format = 24 == info.BPP ? PixelFormats.Bgr24
@ -76,19 +76,5 @@ namespace GameRes.Formats.Leaf
{
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)
throw new InvalidFormatException();
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.AlphaStride = (frame.Width + 3) & ~3;
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)
{
var copy = refs.Clone() as int[];

View File

@ -123,7 +123,7 @@ namespace GameRes.Formats.MAI
if (info.Colors > 0)
{
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;
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;
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)
RleDecoder.Unpack (m_input, (int)m_info.DataLength, m_output, m_pixel_size);
else
@ -324,7 +324,7 @@ namespace GameRes.Formats.MAI
{
var meta = (CmMetaData)info;
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];
if (meta.IsCompressed)
@ -341,20 +341,6 @@ namespace GameRes.Formats.MAI
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)
{
int read = 0;

View File

@ -117,20 +117,7 @@ namespace GameRes.Formats.Pajamas
m_height = (int)info.Height;
m_output = new byte[info.Width*info.Height*m_pixel_size];
if (8 == info.BPP)
ReadPalette();
}
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);
Palette = ImageFormat.ReadPalette (m_input, 0x100, PaletteFormat.Bgr);
}
public void Unpack ()

View File

@ -126,7 +126,7 @@ namespace GameRes.Formats.Vitamin
int input_size = m_info.InputSize - 0x20;
if (m_info.HasPalette)
{
ReadPalette();
Palette = ImageFormat.ReadPalette (m_input.AsStream, 0x100, PaletteFormat.Rgb);
input_size -= 0x300;
}
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
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)
{
throw new System.NotImplementedException ("Gp8Format.Write not implemented");

View File

@ -46,6 +46,17 @@ namespace GameRes
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
{
private BitmapSource m_bitmap;
@ -171,5 +182,43 @@ namespace GameRes
public static ImageFormat Png { get { return s_PngFormat.Value; } }
public static ImageFormat Bmp { get { return s_BmpFormat.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);
}
}
}