mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-27 07:34:00 +08:00
(Gx4Lib): support diff images.
This commit is contained in:
parent
8f21e7558a
commit
bd79789a30
@ -23,6 +23,8 @@
|
|||||||
// IN THE SOFTWARE.
|
// IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.Composition;
|
using System.ComponentModel.Composition;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -32,6 +34,13 @@ using GameRes.Utility;
|
|||||||
|
|
||||||
namespace GameRes.Formats.Unity.Gx4Lib
|
namespace GameRes.Formats.Unity.Gx4Lib
|
||||||
{
|
{
|
||||||
|
internal class VisualDiffData
|
||||||
|
{
|
||||||
|
public string BaseFileName;
|
||||||
|
public int PosX;
|
||||||
|
public int PosY;
|
||||||
|
}
|
||||||
|
|
||||||
[Export(typeof(ArchiveFormat))]
|
[Export(typeof(ArchiveFormat))]
|
||||||
public class DatOpener : ArchiveFormat
|
public class DatOpener : ArchiveFormat
|
||||||
{
|
{
|
||||||
@ -41,6 +50,8 @@ namespace GameRes.Formats.Unity.Gx4Lib
|
|||||||
public override bool IsHierarchic { get { return false; } }
|
public override bool IsHierarchic { get { return false; } }
|
||||||
public override bool CanWrite { get { return false; } }
|
public override bool CanWrite { get { return false; } }
|
||||||
|
|
||||||
|
Lazy<Dictionary<string, VisualDiffData>> DefaultVisualMap = new Lazy<Dictionary<string, VisualDiffData>> (ReadVisualData);
|
||||||
|
|
||||||
public override ArcFile TryOpen (ArcView file)
|
public override ArcFile TryOpen (ArcView file)
|
||||||
{
|
{
|
||||||
uint index_size = file.View.ReadUInt32 (0);
|
uint index_size = file.View.ReadUInt32 (0);
|
||||||
@ -103,6 +114,25 @@ namespace GameRes.Formats.Unity.Gx4Lib
|
|||||||
int buf_width = input.ReadInt32();
|
int buf_width = input.ReadInt32();
|
||||||
int buf_height = input.ReadInt32();
|
int buf_height = input.ReadInt32();
|
||||||
var info = new ImageMetaData { Width = width, Height = height, BPP = 32 };
|
var info = new ImageMetaData { Width = width, Height = height, BPP = 32 };
|
||||||
|
if (DefaultVisualMap.Value.ContainsKey (entry.Name))
|
||||||
|
{
|
||||||
|
var diff_info = DefaultVisualMap.Value[entry.Name];
|
||||||
|
if (VFS.FileExists (diff_info.BaseFileName))
|
||||||
|
{
|
||||||
|
var base_entry = VFS.FindFile (diff_info.BaseFileName);
|
||||||
|
using (var visbase = VFS.OpenImage (base_entry))
|
||||||
|
{
|
||||||
|
var base_decoder = visbase as Gx4ImageDecoder;
|
||||||
|
if (base_decoder != null)
|
||||||
|
{
|
||||||
|
info.OffsetX = diff_info.PosX;
|
||||||
|
info.OffsetY = diff_info.PosY;
|
||||||
|
var pixels = base_decoder.ReadPixels();
|
||||||
|
return new Gx4OverlayDecoder (pixels, base_decoder.Info, input, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return new Gx4ImageDecoder (input, info);
|
return new Gx4ImageDecoder (input, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,26 +234,97 @@ namespace GameRes.Formats.Unity.Gx4Lib
|
|||||||
bits >>= 1;
|
bits >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static Dictionary<string, VisualDiffData> ReadVisualData ()
|
||||||
|
{
|
||||||
|
var map = new Dictionary<string, VisualDiffData>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FormatCatalog.Instance.ReadFileList ("gx4_bsz_visual.lst", (line) => {
|
||||||
|
var parts = line.Split (':', ',');
|
||||||
|
if (parts.Length > 3)
|
||||||
|
{
|
||||||
|
var diff = new VisualDiffData { BaseFileName = parts[1] };
|
||||||
|
if (int.TryParse (parts[2], out diff.PosX) && int.TryParse (parts[3], out diff.PosY))
|
||||||
|
map[parts[0]] = diff;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch { /* ignore errors */ }
|
||||||
|
return map;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Gx4ImageDecoder : BinaryImageDecoder
|
internal class Gx4ImageDecoder : BinaryImageDecoder
|
||||||
{
|
{
|
||||||
|
public int Stride { get; private set; }
|
||||||
|
|
||||||
public Gx4ImageDecoder (IBinaryStream input, ImageMetaData info) : base (input, info)
|
public Gx4ImageDecoder (IBinaryStream input, ImageMetaData info) : base (input, info)
|
||||||
{
|
{
|
||||||
|
Stride = (int)info.Width * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override ImageData GetImageData ()
|
public byte[] ReadPixels ()
|
||||||
{
|
{
|
||||||
m_input.Position = 0x10;
|
m_input.Position = 0x10;
|
||||||
int stride = (int)Info.Width * 4;
|
var pixels = m_input.ReadBytes (Stride * (int)Info.Height);
|
||||||
var pixels = m_input.ReadBytes (stride * (int)Info.Height);
|
|
||||||
for (int i = 0; i < pixels.Length; i += 4)
|
for (int i = 0; i < pixels.Length; i += 4)
|
||||||
{
|
{
|
||||||
byte t = pixels[i];
|
byte t = pixels[i];
|
||||||
pixels[i] = pixels[i+2];
|
pixels[i] = pixels[i+2];
|
||||||
pixels[i+2] = t;
|
pixels[i+2] = t;
|
||||||
}
|
}
|
||||||
return ImageData.CreateFlipped (Info, PixelFormats.Bgra32, null, pixels, stride);
|
return pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override ImageData GetImageData ()
|
||||||
|
{
|
||||||
|
var pixels = ReadPixels();
|
||||||
|
return ImageData.CreateFlipped (Info, PixelFormats.Bgra32, null, pixels, Stride);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class Gx4OverlayDecoder : BinaryImageDecoder
|
||||||
|
{
|
||||||
|
byte[] m_pixels;
|
||||||
|
|
||||||
|
ImageMetaData OverlayInfo { get; set; }
|
||||||
|
|
||||||
|
public Gx4OverlayDecoder (byte[] pixels, ImageMetaData info, IBinaryStream input, ImageMetaData overlay_info)
|
||||||
|
: base (input, info)
|
||||||
|
{
|
||||||
|
m_pixels = pixels;
|
||||||
|
OverlayInfo = overlay_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override ImageData GetImageData ()
|
||||||
|
{
|
||||||
|
m_input.Position = 0x10;
|
||||||
|
int base_stride = (int)Info.Width * 4;
|
||||||
|
int diff_stride = (int)OverlayInfo.Width * 4;
|
||||||
|
var diff = m_input.ReadBytes (diff_stride * (int)OverlayInfo.Height);
|
||||||
|
int dst_line = m_pixels.Length - base_stride * (OverlayInfo.OffsetY + 1) + OverlayInfo.OffsetX * 4;
|
||||||
|
int src_line = diff.Length - diff_stride;
|
||||||
|
for (int y = 0; y < (int)OverlayInfo.Height; ++y)
|
||||||
|
{
|
||||||
|
int dst = dst_line;
|
||||||
|
int src = src_line;
|
||||||
|
for (int x = 0; x < (int)OverlayInfo.Width; ++x)
|
||||||
|
{
|
||||||
|
if (!(0 == diff[src] && 0 == diff[src+1] && 0 == diff[src+2] && 0xFF == diff[src+3]))
|
||||||
|
{
|
||||||
|
m_pixels[dst ] = diff[src+2];
|
||||||
|
m_pixels[dst+1] = diff[src+1];
|
||||||
|
m_pixels[dst+2] = diff[src ];
|
||||||
|
m_pixels[dst+3] = diff[src+3];
|
||||||
|
}
|
||||||
|
dst += 4;
|
||||||
|
src += 4;
|
||||||
|
}
|
||||||
|
dst_line -= base_stride;
|
||||||
|
src_line -= diff_stride;
|
||||||
|
}
|
||||||
|
return ImageData.CreateFlipped (Info, PixelFormats.Bgra32, null, m_pixels, base_stride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user