mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-23 21:55:34 +08:00
(PSB): support "icon" entries and RL compression.
This commit is contained in:
parent
dc1647c5bf
commit
f6f989dd2f
@ -246,26 +246,64 @@ namespace GameRes.Formats.Emote
|
|||||||
var item_value = item.Value as IDictionary;
|
var item_value = item.Value as IDictionary;
|
||||||
if (null == item_value)
|
if (null == item_value)
|
||||||
continue;
|
continue;
|
||||||
var texture = item_value["texture"] as IDictionary;
|
if (item_value.Contains ("texture"))
|
||||||
if (null == texture)
|
{
|
||||||
continue;
|
AddTextureEntry (dir, item.Key, item_value["texture"] as IDictionary);
|
||||||
var pixel = texture["pixel"] as EmChunk;
|
}
|
||||||
|
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)
|
||||||
|
return;
|
||||||
|
var pixel = texture["pixel"] as EmChunk;
|
||||||
|
if (null == pixel)
|
||||||
|
return;
|
||||||
|
var entry = new TexEntry {
|
||||||
|
Name = name.ToString(),
|
||||||
|
Type = "image",
|
||||||
|
Offset = DataOffset + pixel.Offset,
|
||||||
|
Size = (uint)pixel.Length,
|
||||||
|
TexType = texture["type"].ToString(),
|
||||||
|
Width = Convert.ToInt32 (texture["width"]),
|
||||||
|
Height = Convert.ToInt32 (texture["height"]),
|
||||||
|
TruncatedWidth = Convert.ToInt32 (texture["truncated_width"]),
|
||||||
|
TruncatedHeight = Convert.ToInt32 (texture["truncated_height"]),
|
||||||
|
};
|
||||||
|
dir.Add (entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
if (null == pixel)
|
||||||
continue;
|
continue;
|
||||||
var entry = new TexEntry {
|
var entry = new TexEntry {
|
||||||
Name = item.Key.ToString(),
|
Name = name.ToString()+'#'+icon.Key.ToString(),
|
||||||
Type = "image",
|
Type = "image",
|
||||||
Offset = DataOffset + pixel.Offset,
|
Offset = DataOffset + pixel.Offset,
|
||||||
Size = (uint)pixel.Length,
|
Size = (uint)pixel.Length,
|
||||||
TexType = texture["type"].ToString(),
|
Width = Convert.ToInt32 (layer["width"]),
|
||||||
Width = Convert.ToInt32 (texture["width"]),
|
Height = Convert.ToInt32 (layer["height"]),
|
||||||
Height = Convert.ToInt32 (texture["height"]),
|
OffsetX = Convert.ToInt32 (layer["originX"]),
|
||||||
TruncatedWidth = Convert.ToInt32 (texture["truncated_width"]),
|
OffsetY = Convert.ToInt32 (layer["originY"]),
|
||||||
TruncatedHeight = Convert.ToInt32 (texture["truncated_height"]),
|
TexType = layer.Contains ("compress") ? layer["compress"].ToString() : "RGBA8",
|
||||||
};
|
};
|
||||||
|
entry.TruncatedWidth = entry.Width;
|
||||||
|
entry.TruncatedHeight = entry.Height;
|
||||||
dir.Add (entry);
|
dir.Add (entry);
|
||||||
}
|
}
|
||||||
return dir;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int m_names;
|
int m_names;
|
||||||
@ -651,6 +689,8 @@ namespace GameRes.Formats.Emote
|
|||||||
ReadA8L8 (pixels, stride);
|
ReadA8L8 (pixels, stride);
|
||||||
else if ("RGBA4444" == m_info.TexType)
|
else if ("RGBA4444" == m_info.TexType)
|
||||||
ReadRgba4444 (pixels, stride);
|
ReadRgba4444 (pixels, stride);
|
||||||
|
else if ("RL" == m_info.TexType)
|
||||||
|
ReadRle (pixels, stride);
|
||||||
else
|
else
|
||||||
throw new NotImplementedException (string.Format ("PSB texture format '{0}' not implemented", m_info.TexType));
|
throw new NotImplementedException (string.Format ("PSB texture format '{0}' not implemented", m_info.TexType));
|
||||||
return ImageData.Create (m_info, PixelFormats.Bgra32, null, pixels, stride);
|
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