From 13cf289bae053a01f55aea618d9d5335fb4ac81e Mon Sep 17 00:00:00 2001 From: morkt Date: Sat, 14 Jan 2017 16:27:11 +0400 Subject: [PATCH] (ImageFormat.ReadPalette): new static methods. Generalized image palette deserializations. --- ArcFormats/AZSys/ImageTYP1.cs | 19 +----------- ArcFormats/Abogado/ImageKG.cs | 16 +--------- ArcFormats/Bishop/ImageBSG.cs | 11 +------ ArcFormats/BlackCyc/ImageDWQ.cs | 21 ++----------- ArcFormats/EmonEngine/ImageBMP.cs | 18 +----------- ArcFormats/Entis/EriReader.cs | 8 +++++ ArcFormats/Entis/ImageERI.cs | 13 ++------ ArcFormats/Eushully/ImageAGF.cs | 15 +--------- ArcFormats/ExHibit/ImageGYU.cs | 16 +--------- ArcFormats/FC01/ArcMCA.cs | 15 +--------- ArcFormats/FC01/ImageCLM.cs | 14 --------- ArcFormats/Gpk2/ImageGFB.cs | 8 ++--- ArcFormats/GsPack/ImageGS.cs | 12 -------- ArcFormats/ImagePSD.cs | 13 ++------ ArcFormats/ImageSeraph.cs | 17 +---------- ArcFormats/Ipac/ImageIES.cs | 16 +--------- ArcFormats/Ivory/ImageMMD.cs | 22 +------------- ArcFormats/Ivory/ImageSG.cs | 18 ++---------- ArcFormats/Leaf/ImageLGF.cs | 16 +--------- ArcFormats/LiveMaker/ImageGAL.cs | 16 +--------- ArcFormats/MAI/ImageMAI.cs | 20 ++----------- ArcFormats/Pajamas/ImageEPA.cs | 15 +--------- ArcFormats/Vitamin/ImageSBI.cs | 16 +--------- ArcFormats/elf/ImageGP8.cs | 14 --------- GameRes/Image.cs | 49 +++++++++++++++++++++++++++++++ 25 files changed, 87 insertions(+), 331 deletions(-) diff --git a/ArcFormats/AZSys/ImageTYP1.cs b/ArcFormats/AZSys/ImageTYP1.cs index aad4243f..dbcc1c46 100644 --- a/ArcFormats/AZSys/ImageTYP1.cs +++ b/ArcFormats/AZSys/ImageTYP1.cs @@ -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) { diff --git a/ArcFormats/Abogado/ImageKG.cs b/ArcFormats/Abogado/ImageKG.cs index 9f749f3c..8eacd5d6 100644 --- a/ArcFormats/Abogado/ImageKG.cs +++ b/ArcFormats/Abogado/ImageKG.cs @@ -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); diff --git a/ArcFormats/Bishop/ImageBSG.cs b/ArcFormats/Bishop/ImageBSG.cs index 827bb623..6b4f5081 100644 --- a/ArcFormats/Bishop/ImageBSG.cs +++ b/ArcFormats/Bishop/ImageBSG.cs @@ -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 diff --git a/ArcFormats/BlackCyc/ImageDWQ.cs b/ArcFormats/BlackCyc/ImageDWQ.cs index 5932f0e1..3a0605b3 100644 --- a/ArcFormats/BlackCyc/ImageDWQ.cs +++ b/ArcFormats/BlackCyc/ImageDWQ.cs @@ -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]; diff --git a/ArcFormats/EmonEngine/ImageBMP.cs b/ArcFormats/EmonEngine/ImageBMP.cs index c1d77cbe..d38df339 100644 --- a/ArcFormats/EmonEngine/ImageBMP.cs +++ b/ArcFormats/EmonEngine/ImageBMP.cs @@ -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"); diff --git a/ArcFormats/Entis/EriReader.cs b/ArcFormats/Entis/EriReader.cs index 57319766..5e58b4f0 100644 --- a/ArcFormats/Entis/EriReader.cs +++ b/ArcFormats/Entis/EriReader.cs @@ -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(); diff --git a/ArcFormats/Entis/ImageERI.cs b/ArcFormats/Entis/ImageERI.cs index 1688c3bd..27cbab21 100644 --- a/ArcFormats/Entis/ImageERI.cs +++ b/ArcFormats/Entis/ImageERI.cs @@ -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) diff --git a/ArcFormats/Eushully/ImageAGF.cs b/ArcFormats/Eushully/ImageAGF.cs index cbc6c4e6..4c8d3cf9 100644 --- a/ArcFormats/Eushully/ImageAGF.cs +++ b/ArcFormats/Eushully/ImageAGF.cs @@ -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)) diff --git a/ArcFormats/ExHibit/ImageGYU.cs b/ArcFormats/ExHibit/ImageGYU.cs index e0ad42d0..72aa8435 100644 --- a/ArcFormats/ExHibit/ImageGYU.cs +++ b/ArcFormats/ExHibit/ImageGYU.cs @@ -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; diff --git a/ArcFormats/FC01/ArcMCA.cs b/ArcFormats/FC01/ArcMCA.cs index ff80dbd3..dbbd68c5 100644 --- a/ArcFormats/FC01/ArcMCA.cs +++ b/ArcFormats/FC01/ArcMCA.cs @@ -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 }; diff --git a/ArcFormats/FC01/ImageCLM.cs b/ArcFormats/FC01/ImageCLM.cs index b30276fc..9b775ff5 100644 --- a/ArcFormats/FC01/ImageCLM.cs +++ b/ArcFormats/FC01/ImageCLM.cs @@ -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"); diff --git a/ArcFormats/Gpk2/ImageGFB.cs b/ArcFormats/Gpk2/ImageGFB.cs index 4d0d1c9e..a8ac96ca 100644 --- a/ArcFormats/Gpk2/ImageGFB.cs +++ b/ArcFormats/Gpk2/ImageGFB.cs @@ -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]; diff --git a/ArcFormats/GsPack/ImageGS.cs b/ArcFormats/GsPack/ImageGS.cs index c515c99c..0b784831 100644 --- a/ArcFormats/GsPack/ImageGS.cs +++ b/ArcFormats/GsPack/ImageGS.cs @@ -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); - } } } diff --git a/ArcFormats/ImagePSD.cs b/ArcFormats/ImagePSD.cs index 9d58d0d8..b24e8536 100644 --- a/ArcFormats/ImagePSD.cs +++ b/ArcFormats/ImagePSD.cs @@ -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 () diff --git a/ArcFormats/ImageSeraph.cs b/ArcFormats/ImageSeraph.cs index 59454e35..8b82a07b 100644 --- a/ArcFormats/ImageSeraph.cs +++ b/ArcFormats/ImageSeraph.cs @@ -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 () diff --git a/ArcFormats/Ipac/ImageIES.cs b/ArcFormats/Ipac/ImageIES.cs index 75e9a3c1..7794181b 100644 --- a/ArcFormats/Ipac/ImageIES.cs +++ b/ArcFormats/Ipac/ImageIES.cs @@ -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); - } } } diff --git a/ArcFormats/Ivory/ImageMMD.cs b/ArcFormats/Ivory/ImageMMD.cs index 8a0ef6e2..9fcaaaa8 100644 --- a/ArcFormats/Ivory/ImageMMD.cs +++ b/ArcFormats/Ivory/ImageMMD.cs @@ -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"); diff --git a/ArcFormats/Ivory/ImageSG.cs b/ArcFormats/Ivory/ImageSG.cs index 59003ef6..f7d31eb5 100644 --- a/ArcFormats/Ivory/ImageSG.cs +++ b/ArcFormats/Ivory/ImageSG.cs @@ -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 () { diff --git a/ArcFormats/Leaf/ImageLGF.cs b/ArcFormats/Leaf/ImageLGF.cs index 914d527a..6551acab 100644 --- a/ArcFormats/Leaf/ImageLGF.cs +++ b/ArcFormats/Leaf/ImageLGF.cs @@ -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); - } } } diff --git a/ArcFormats/LiveMaker/ImageGAL.cs b/ArcFormats/LiveMaker/ImageGAL.cs index 9bc66e16..66e6da3c 100644 --- a/ArcFormats/LiveMaker/ImageGAL.cs +++ b/ArcFormats/LiveMaker/ImageGAL.cs @@ -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[]; diff --git a/ArcFormats/MAI/ImageMAI.cs b/ArcFormats/MAI/ImageMAI.cs index 8a38ba05..a83d47f0 100644 --- a/ArcFormats/MAI/ImageMAI.cs +++ b/ArcFormats/MAI/ImageMAI.cs @@ -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; diff --git a/ArcFormats/Pajamas/ImageEPA.cs b/ArcFormats/Pajamas/ImageEPA.cs index d970f067..eea54184 100644 --- a/ArcFormats/Pajamas/ImageEPA.cs +++ b/ArcFormats/Pajamas/ImageEPA.cs @@ -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 () diff --git a/ArcFormats/Vitamin/ImageSBI.cs b/ArcFormats/Vitamin/ImageSBI.cs index b957d457..051a539a 100644 --- a/ArcFormats/Vitamin/ImageSBI.cs +++ b/ArcFormats/Vitamin/ImageSBI.cs @@ -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 () { diff --git a/ArcFormats/elf/ImageGP8.cs b/ArcFormats/elf/ImageGP8.cs index 18192ccc..b56f999a 100644 --- a/ArcFormats/elf/ImageGP8.cs +++ b/ArcFormats/elf/ImageGP8.cs @@ -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"); diff --git a/GameRes/Image.cs b/GameRes/Image.cs index 1773ec93..cae12e92 100644 --- a/GameRes/Image.cs +++ b/GameRes/Image.cs @@ -46,6 +46,17 @@ namespace GameRes public override string Type { get { return "image"; } } } + /// + /// Enumeration representing possible palette serialization formats. + /// + 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; } } + + /// + /// Desereialize color map from stream, consisting of specified number of + /// stored in specified . + /// Default number of colors is 256 and format is 4-byte BGRX (where X is an unsignificant byte). + /// + 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 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); + } } }