From 913d6e6817045e1e9b843b4a7ff7f549da4ed68e Mon Sep 17 00:00:00 2001 From: morkt Date: Sun, 31 Dec 2017 09:04:16 +0400 Subject: [PATCH] (BET): recognize non-compressed images. --- Legacy/System21/ImageBET.cs | 100 ++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 39 deletions(-) diff --git a/Legacy/System21/ImageBET.cs b/Legacy/System21/ImageBET.cs index dae9015a..ae988f9c 100644 --- a/Legacy/System21/ImageBET.cs +++ b/Legacy/System21/ImageBET.cs @@ -23,6 +23,7 @@ // IN THE SOFTWARE. // +using System; using System.ComponentModel.Composition; using System.IO; using System.Windows.Media; @@ -35,53 +36,36 @@ namespace GameRes.Formats.System21 public class BetFormat : ImageFormat { public override string Tag { get { return "BET"; } } - public override string Description { get { return "System21 compressed image format"; } } - public override uint Signature { get { return 0x44445A53; } } // 'SZDD' + public override string Description { get { return "System21 image format"; } } + public override uint Signature { get { return 0; } } public override ImageMetaData ReadMetaData (IBinaryStream file) { if (!file.Name.HasExtension (".bet")) return null; - using (var lz = OpenLzStream (file.AsStream)) - using (var input = new BinaryStream (lz, file.Name)) - { - uint w = input.ReadUInt32(); - uint h = input.ReadUInt32(); - int bpp = input.ReadUInt16(); - if ((bpp != 24 && bpp != 8) || 0 == w || w > 0x8000 || 0 == h || h > 0x8000) - return null; - return new ImageMetaData { Width = w, Height = h, BPP = bpp }; - } + uint w = file.ReadUInt32(); + uint h = file.ReadUInt32(); + int bpp = file.ReadUInt16(); + if ((bpp != 24 && bpp != 8) || 0 == w || w > 0x8000 || 0 == h || h > 0x8000) + return null; + return new ImageMetaData { Width = w, Height = h, BPP = bpp }; } - public override ImageData Read (IBinaryStream file, ImageMetaData info) + public override ImageData Read (IBinaryStream input, ImageMetaData info) { - using (var input = OpenLzStream (file.AsStream)) - { - int stride = (int)info.Width * info.BPP / 8; - var pixels = new byte[stride * (int)info.Height]; - for (int i = 0; i < 10; ++i) - input.ReadByte(); - BitmapPalette palette = null; - if (8 == info.BPP) - palette = ReadPalette (input); - if (input.Read (pixels, 0, pixels.Length) != pixels.Length) - throw new InvalidFormatException(); - for (int i = 0; i < pixels.Length; ++i) - pixels[i] ^= 0xFF; - PixelFormat format = 8 == info.BPP ? PixelFormats.Indexed8 : PixelFormats.Bgr24; - return ImageData.CreateFlipped (info, format, palette, pixels, stride); - } - } - - Stream OpenLzStream (Stream input) - { - input.Position = 0xE; - var lz = new LzssStream (input, LzssMode.Decompress, true); - lz.Config.FrameSize = 0x1000; - lz.Config.FrameFill = 0x20; - lz.Config.FrameInitPos = 0x1000 - 0x10; - return lz; + int stride = (int)info.Width * info.BPP / 8; + int bitmap_length = stride * (int)info.Height; + var pixels = new byte[Math.Max (bitmap_length, 10)]; + input.Read (pixels, 0, 10); // input might be non-seekable + BitmapPalette palette = null; + if (8 == info.BPP) + palette = ReadPalette (input.AsStream); + if (input.Read (pixels, 0, bitmap_length) != bitmap_length) + throw new InvalidFormatException(); + for (int i = 0; i < bitmap_length; ++i) + pixels[i] ^= 0xFF; + PixelFormat format = 8 == info.BPP ? PixelFormats.Indexed8 : PixelFormats.Bgr24; + return ImageData.CreateFlipped (info, format, palette, pixels, stride); } public override void Write (Stream file, ImageData image) @@ -89,4 +73,42 @@ namespace GameRes.Formats.System21 throw new System.NotImplementedException ("BetFormat.Write not implemented"); } } + + [Export(typeof(ImageFormat))] + public class LzBetFormat : BetFormat + { + public override string Tag { get { return "BET/SZDD"; } } + public override string Description { get { return "System21 compressed image format"; } } + public override uint Signature { get { return 0x44445A53; } } // 'SZDD' + public override bool CanWrite { get { return false; } } + + public override ImageMetaData ReadMetaData (IBinaryStream file) + { + if (!file.Name.HasExtension (".bet")) + return null; + using (var input = OpenLzStream (file)) + return base.ReadMetaData (input); + } + + public override ImageData Read (IBinaryStream file, ImageMetaData info) + { + using (var input = OpenLzStream (file)) + return base.Read (input, info); + } + + IBinaryStream OpenLzStream (IBinaryStream input) + { + input.Position = 0xE; + var lz = new LzssStream (input.AsStream, LzssMode.Decompress, true); + lz.Config.FrameSize = 0x1000; + lz.Config.FrameFill = 0x20; + lz.Config.FrameInitPos = 0x1000 - 0x10; + return new BinaryStream (lz, input.Name); // XXX stream is unseekable + } + + public override void Write (Stream file, ImageData image) + { + throw new System.NotImplementedException ("LzBetFormat.Write not implemented"); + } + } }