From 6e0a0a612f32d11a2041a284fee0441acba9fdde Mon Sep 17 00:00:00 2001 From: morkt Date: Tue, 2 Aug 2016 18:18:04 +0400 Subject: [PATCH] (RctFormat): apply mask if accompanying file is present. --- ArcFormats/Majiro/ImageRCT.cs | 49 ++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/ArcFormats/Majiro/ImageRCT.cs b/ArcFormats/Majiro/ImageRCT.cs index 7dff2ad0..0d2fed31 100644 --- a/ArcFormats/Majiro/ImageRCT.cs +++ b/ArcFormats/Majiro/ImageRCT.cs @@ -65,6 +65,7 @@ namespace GameRes.Formats.Majiro public override uint Signature { get { return 0x9a925a98; } } public bool OverlayFrames = true; + public bool ApplyMask = true; public static Dictionary KnownKeys = new Dictionary(); @@ -135,9 +136,55 @@ namespace GameRes.Formats.Majiro var pixels = ReadPixelsData (file, meta); if (base_image != null) pixels = CombineImage (base_image, pixels); + + if (ApplyMask) + { + var base_name = Path.GetFileNameWithoutExtension (meta.FileName); + var mask_name = base_name + "_.rc8"; + mask_name = VFS.CombinePath (VFS.GetDirectoryName (meta.FileName), mask_name); + if (VFS.FileExists (mask_name)) + { + try + { + return ApplyMaskToImage (meta, pixels, mask_name); + } + catch { /* ignore mask read errors */ } + } + } return ImageData.Create (meta, PixelFormats.Bgr24, null, pixels, (int)meta.Width*3); } + ImageData ApplyMaskToImage (RctMetaData info, byte[] image, string mask_name) + { + using (var mask_file = VFS.OpenSeekableStream (mask_name)) + { + var format = FindFormat (mask_file, mask_name); + if (null == format || !(format.Item1 is Rc8Format) + || info.Width != format.Item2.Width || info.Height != format.Item2.Height) + throw new InvalidFormatException(); + + using (var reader = new Rc8Format.Reader (mask_file, format.Item2)) + { + reader.Unpack(); + var palette = reader.Palette; + int dst_stride = (int)info.Width * 4; + var pixels = new byte[dst_stride * (int)info.Height]; + var alpha = reader.Data; + int a_src = 0; + int src = 0; + for (int dst = 0; dst < pixels.Length; dst += 4) + { + pixels[dst ] = image[src++]; + pixels[dst+1] = image[src++]; + pixels[dst+2] = image[src++]; + var color = palette[alpha[a_src++]]; + pixels[dst+3] = (byte)~((color.B + color.G + color.R) / 3); + } + return ImageData.Create (info, PixelFormats.Bgra32, null, pixels, dst_stride); + } + } + } + byte[] CombineImage (byte[] base_image, byte[] overlay) { for (int i = 2; i < base_image.Length; i += 3) @@ -607,7 +654,6 @@ namespace GameRes.Formats.Majiro public override ImageData Read (Stream file, ImageMetaData info) { - file.Position = 0x14; using (var reader = new Reader (file, info)) { reader.Unpack(); @@ -634,6 +680,7 @@ namespace GameRes.Formats.Majiro public Reader (Stream file, ImageMetaData info) { m_width = info.Width; + file.Position = 0x14; var palette_data = new byte[0x300]; if (palette_data.Length != file.Read (palette_data, 0, palette_data.Length)) throw new InvalidFormatException();