diff --git a/ArcFormats/EmonEngine/ArcEME.cs b/ArcFormats/EmonEngine/ArcEME.cs index e41ed383..7ac79026 100644 --- a/ArcFormats/EmonEngine/ArcEME.cs +++ b/ArcFormats/EmonEngine/ArcEME.cs @@ -2,7 +2,7 @@ //! \date Tue Mar 15 08:13:00 2016 //! \brief Emon Engine (えもんエンジン) resource archives. // -// Copyright (C) 2016 by morkt +// Copyright (C) 2016-2017 by morkt // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to @@ -27,7 +27,6 @@ using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.IO; -using System.Text; using GameRes.Compression; using GameRes.Utility; @@ -91,8 +90,6 @@ namespace GameRes.Formats.EmonEngine return base.OpenEntry (arc, entry); if (3 == ement.SubType) return OpenScript (emarc, ement); - else if (4 == ement.SubType) - return OpenImage (emarc, ement); else if (5 == ement.SubType && entry.Size > 4) return OpenT5 (emarc, ement); else @@ -140,20 +137,32 @@ namespace GameRes.Formats.EmonEngine } } - Stream OpenImage (EmeArchive arc, EmEntry entry) + public override IImageDecoder OpenImage (ArcFile arc, Entry entry) { - var header = new byte[40]; - Encoding.ASCII.GetBytes ("EMBM", 0, 4, header, 0); - LittleEndian.Pack ((ushort)entry.LzssFrameSize, header, 4); - LittleEndian.Pack ((ushort)entry.LzssInitPos, header, 6); - arc.File.View.Read (entry.Offset, header, 8, 32); - Decrypt (header, 8, 32, arc.Key); - uint entry_size = entry.Size; - uint colors = LittleEndian.ToUInt16 (header, 14); - if (0 != colors && header[0] != 7) - entry_size += Math.Max (colors, 3u) * 4; - var input = arc.File.CreateStream (entry.Offset+32, entry_size); - return new PrefixStream (header, input); + const int header_size = 32; + var ement = (EmEntry)entry; + if (ement.SubType != 4) + return base.OpenImage (arc, entry); + var emarc = (EmeArchive)arc; + var header = arc.File.View.ReadBytes (entry.Offset, header_size); + Decrypt (header, 0, header_size, emarc.Key); + var info = new EmMetaData { + LzssFrameSize = ement.LzssFrameSize, + LzssInitPos = ement.LzssInitPos, + BPP = header.ToUInt16 (0) & 0xFF, + Width = header.ToUInt16 (2), + Height = header.ToUInt16 (4), + Colors = header.ToUInt16 (6), + Stride = header.ToInt32 (8), + OffsetX = header.ToInt32 (0xC), + OffsetY = header.ToInt32 (0x10), + DataOffset = header_size, + }; + uint entry_size = entry.Size + header_size; + if (0 != info.Colors && header[0] != 7) + entry_size += (uint)Math.Max (info.Colors, 3) * 4; + var input = arc.File.CreateStream (entry.Offset, entry_size); + return new EmeImageDecoder (input, info); } Stream OpenT5 (EmeArchive arc, EmEntry entry) diff --git a/ArcFormats/EmonEngine/ImageBMP.cs b/ArcFormats/EmonEngine/ImageBMP.cs index d38df339..f96effb3 100644 --- a/ArcFormats/EmonEngine/ImageBMP.cs +++ b/ArcFormats/EmonEngine/ImageBMP.cs @@ -2,7 +2,7 @@ //! \date Wed Mar 16 01:08:47 2016 //! \brief Emon Engine compressed images. // -// Copyright (C) 2016 by morkt +// Copyright (C) 2016-2017 by morkt // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to @@ -24,7 +24,6 @@ // using System; -using System.ComponentModel.Composition; using System.IO; using System.Windows.Media; using System.Windows.Media.Imaging; @@ -41,47 +40,23 @@ namespace GameRes.Formats.EmonEngine public int DataOffset; } - [Export(typeof(ImageFormat))] - public class EmFormat : ImageFormat + internal class EmeImageDecoder : BinaryImageDecoder { - public override string Tag { get { return "EM/BMP"; } } - public override string Description { get { return "Emon Engine image format"; } } - // this is an artificial prefix embedded into stream by EmeOpener.OpenImage - public override uint Signature { get { return 0x4D424D45; } } // 'EMBM' - - public EmFormat () + public EmeImageDecoder (IBinaryStream input, EmMetaData info) : base (input, info) { - Extensions = new string[] { "bmp" }; } - public override ImageMetaData ReadMetaData (IBinaryStream stream) + protected override ImageData GetImageData () { - stream.ReadInt32(); - var info = new EmMetaData(); - info.LzssFrameSize = stream.ReadUInt16(); - info.LzssInitPos = stream.ReadUInt16(); - info.BPP = stream.ReadUInt16() & 0xFF; - info.Width = stream.ReadUInt16(); - info.Height = stream.ReadUInt16(); - info.Colors = stream.ReadUInt16(); - info.Stride = stream.ReadInt32(); - info.OffsetX = stream.ReadInt32(); - info.OffsetY = stream.ReadInt32(); - info.DataOffset = 40; - return info; - } - - public override ImageData Read (IBinaryStream stream, ImageMetaData info) - { - var meta = (EmMetaData)info; - stream.Position = meta.DataOffset; + var meta = (EmMetaData)Info; + m_input.Position = meta.DataOffset; BitmapPalette palette = null; if (meta.Colors != 0) - palette = ReadPalette (stream.AsStream, Math.Max (meta.Colors, 3), PaletteFormat.RgbX); - var pixels = new byte[meta.Stride * (int)info.Height]; + palette = ImageFormat.ReadPalette (m_input.AsStream, Math.Max (meta.Colors, 3), PaletteFormat.RgbX); + var pixels = new byte[meta.Stride * (int)meta.Height]; if (meta.LzssFrameSize != 0) { - using (var lzss = new LzssStream (stream.AsStream, LzssMode.Decompress, true)) + using (var lzss = new LzssStream (m_input.AsStream, LzssMode.Decompress, true)) { lzss.Config.FrameSize = meta.LzssFrameSize; lzss.Config.FrameInitPos = meta.LzssInitPos; @@ -91,11 +66,11 @@ namespace GameRes.Formats.EmonEngine } else { - if (pixels.Length != stream.Read (pixels, 0, pixels.Length)) + if (pixels.Length != m_input.Read (pixels, 0, pixels.Length)) throw new EndOfStreamException(); } if (7 == meta.BPP) - return ImageData.Create (info, PixelFormats.Gray8, palette, pixels, meta.Stride); + return ImageData.Create (Info, PixelFormats.Gray8, palette, pixels, meta.Stride); PixelFormat format; if (32 == meta.BPP) @@ -104,12 +79,7 @@ namespace GameRes.Formats.EmonEngine format = PixelFormats.Bgr24; else format = PixelFormats.Indexed8; - return ImageData.CreateFlipped (info, format, palette, pixels, meta.Stride); - } - - public override void Write (Stream file, ImageData image) - { - throw new System.NotImplementedException ("EmFormat.Write not implemented"); + return ImageData.CreateFlipped (Info, format, palette, pixels, meta.Stride); } } }