mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-27 15:44:00 +08:00
(PSB): support "icon" entries and RL compression.
This commit is contained in:
parent
dc1647c5bf
commit
f6f989dd2f
@ -246,14 +246,27 @@ namespace GameRes.Formats.Emote
|
||||
var item_value = item.Value as IDictionary;
|
||||
if (null == item_value)
|
||||
continue;
|
||||
var texture = item_value["texture"] as IDictionary;
|
||||
if (item_value.Contains ("texture"))
|
||||
{
|
||||
AddTextureEntry (dir, item.Key, item_value["texture"] as IDictionary);
|
||||
}
|
||||
else if (item_value.Contains ("icon"))
|
||||
{
|
||||
AddIconEntry (dir, item.Key, item_value["icon"] as IDictionary);
|
||||
}
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
void AddTextureEntry (List<Entry> dir, object name, IDictionary texture)
|
||||
{
|
||||
if (null == texture)
|
||||
continue;
|
||||
return;
|
||||
var pixel = texture["pixel"] as EmChunk;
|
||||
if (null == pixel)
|
||||
continue;
|
||||
return;
|
||||
var entry = new TexEntry {
|
||||
Name = item.Key.ToString(),
|
||||
Name = name.ToString(),
|
||||
Type = "image",
|
||||
Offset = DataOffset + pixel.Offset,
|
||||
Size = (uint)pixel.Length,
|
||||
@ -265,7 +278,32 @@ namespace GameRes.Formats.Emote
|
||||
};
|
||||
dir.Add (entry);
|
||||
}
|
||||
return dir;
|
||||
|
||||
void AddIconEntry (List<Entry> dir, object name, IDictionary icon_list)
|
||||
{
|
||||
if (null == icon_list)
|
||||
return;
|
||||
foreach (DictionaryEntry icon in icon_list)
|
||||
{
|
||||
var layer = icon.Value as IDictionary;
|
||||
var pixel = layer["pixel"] as EmChunk;
|
||||
if (null == pixel)
|
||||
continue;
|
||||
var entry = new TexEntry {
|
||||
Name = name.ToString()+'#'+icon.Key.ToString(),
|
||||
Type = "image",
|
||||
Offset = DataOffset + pixel.Offset,
|
||||
Size = (uint)pixel.Length,
|
||||
Width = Convert.ToInt32 (layer["width"]),
|
||||
Height = Convert.ToInt32 (layer["height"]),
|
||||
OffsetX = Convert.ToInt32 (layer["originX"]),
|
||||
OffsetY = Convert.ToInt32 (layer["originY"]),
|
||||
TexType = layer.Contains ("compress") ? layer["compress"].ToString() : "RGBA8",
|
||||
};
|
||||
entry.TruncatedWidth = entry.Width;
|
||||
entry.TruncatedHeight = entry.Height;
|
||||
dir.Add (entry);
|
||||
}
|
||||
}
|
||||
|
||||
int m_names;
|
||||
@ -651,6 +689,8 @@ namespace GameRes.Formats.Emote
|
||||
ReadA8L8 (pixels, stride);
|
||||
else if ("RGBA4444" == m_info.TexType)
|
||||
ReadRgba4444 (pixels, stride);
|
||||
else if ("RL" == m_info.TexType)
|
||||
ReadRle (pixels, stride);
|
||||
else
|
||||
throw new NotImplementedException (string.Format ("PSB texture format '{0}' not implemented", m_info.TexType));
|
||||
return ImageData.Create (m_info, PixelFormats.Bgra32, null, pixels, stride);
|
||||
@ -734,5 +774,28 @@ namespace GameRes.Formats.Emote
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReadRle (byte[] output, int dst_stride)
|
||||
{
|
||||
const int pixel_size = 4;
|
||||
m_input.Position = 0;
|
||||
int dst = 0;
|
||||
while (dst < output.Length)
|
||||
{
|
||||
int count = m_input.ReadUInt8();
|
||||
if (0 == (count & 0x80))
|
||||
{
|
||||
count = pixel_size * (count + 1);
|
||||
dst += m_input.Read (output, dst, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = pixel_size * ((count & 0x7F) + 3);
|
||||
m_input.Read (output, dst, pixel_size);
|
||||
Binary.CopyOverlapped (output, dst, dst+pixel_size, count-pixel_size);
|
||||
dst += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user