();
+ while (current_offset < file.MaxOffset)
+ {
+ uint packed_size = file.View.ReadUInt32 (current_offset+1);
+ if (0 == packed_size || current_offset+packed_size+0x19 > file.MaxOffset)
+ return null;
+ var entry = new Entry {
+ Name = string.Format ("{0}#{1:D3}.IAF", base_name, dir.Count),
+ Type = "image",
+ Offset = current_offset,
+ Size = packed_size + 0x19,
+ };
+ dir.Add (entry);
+ current_offset += entry.Size;
+ }
+ return new ArcFile (file, this, dir);
+ }
+ }
+}
diff --git a/ArcFormats/Triangle/ImageIAF.cs b/ArcFormats/Triangle/ImageIAF.cs
index 46010b2c..12c86512 100644
--- a/ArcFormats/Triangle/ImageIAF.cs
+++ b/ArcFormats/Triangle/ImageIAF.cs
@@ -76,46 +76,20 @@ namespace GameRes.Formats.Triangle
if (Math.Abs (x) > 4096 || Math.Abs (y) > 4096)
return null;
int pack_type = (unpacked_size >> 30) & 3;
+ if (3 == pack_type)
+ return null;
unpacked_size &= (int)~0xC0000000;
stream.Position = data_offset;
- byte[] bmp;
- if (0 == pack_type)
- {
- using (var reader = new LzssReader (stream, (int)stream.Length-12, 0x26))
- {
- reader.Unpack();
- bmp = reader.Data;
- }
- }
- else if (2 == pack_type)
- {
- using (var reader = new RleReader (stream, (int)stream.Length-12, 0x26))
- {
- reader.Unpack();
- bmp = reader.Data;
- }
- }
- else if (1 == pack_type)
- {
- bmp = new byte[0x26];
- stream.Read (bmp, 0, bmp.Length);
- }
- else
- {
- return null;
- }
+ byte[] bmp = UnpackBitmap (stream, pack_type, packed_size, 0x26);
if (bmp[0] != 'B' && bmp[0] != 'C' || bmp[1] != 'M')
return null;
- int width = LittleEndian.ToInt32 (bmp, 0x12);
- int height = LittleEndian.ToInt32 (bmp, 0x16);
- int bpp = LittleEndian.ToInt16 (bmp, 0x1c);
return new IafMetaData
{
- Width = (uint)width,
- Height = (uint)height,
+ Width = LittleEndian.ToUInt32 (bmp, 0x12),
+ Height = LittleEndian.ToUInt32 (bmp, 0x16),
OffsetX = x,
OffsetY = y,
- BPP = bpp,
+ BPP = LittleEndian.ToInt16 (bmp, 0x1c),
DataOffset = data_offset,
PackedSize = packed_size,
UnpackedSize = unpacked_size,
@@ -125,41 +99,16 @@ namespace GameRes.Formats.Triangle
public override ImageData Read (Stream stream, ImageMetaData info)
{
- var meta = info as IafMetaData;
- if (null == meta)
- throw new ArgumentException ("IafFormat.Read should be supplied with IafMetaData", "info");
-
+ var meta = (IafMetaData)info;
stream.Position = meta.DataOffset;
- byte[] bitmap;
- if (2 == meta.PackType)
- {
- using (var reader = new RleReader (stream, meta.PackedSize, meta.UnpackedSize))
- {
- reader.Unpack();
- bitmap = reader.Data;
- }
- }
- else if (0 == meta.PackType)
- {
- using (var reader = new LzssReader (stream, meta.PackedSize, meta.UnpackedSize))
- {
- reader.Unpack();
- bitmap = reader.Data;
- }
- }
- else
- {
- bitmap = new byte[meta.UnpackedSize];
- if (bitmap.Length != stream.Read (bitmap, 0, bitmap.Length))
- throw new InvalidFormatException ("Unexpected end of file");
- }
+ var bitmap = UnpackBitmap (stream, meta.PackType, meta.PackedSize, meta.UnpackedSize);
if ('C' == bitmap[0])
{
bitmap[0] = (byte)'B';
if (info.BPP > 8)
bitmap = ConvertCM (bitmap, (int)info.Width, (int)info.Height, info.BPP);
}
- if (meta.BPP >= 24) // currently alpha channel could be applied to 24+bpp bitmaps only
+ if (info.BPP >= 24) // currently alpha channel could be applied to 24+bpp bitmaps only
{
try
{
@@ -172,7 +121,7 @@ namespace GameRes.Formats.Triangle
uint alpha_width = LittleEndian.ToUInt32 (bitmap, bmp_size+0x12);
uint alpha_height = LittleEndian.ToUInt32 (bitmap, bmp_size+0x16);
if (info.Width == alpha_width && info.Height == alpha_height)
- return BitmapWithAlphaChannel (meta, bitmap, bmp_size);
+ return BitmapWithAlphaChannel (info, bitmap, bmp_size);
}
}
}
@@ -186,6 +135,35 @@ namespace GameRes.Formats.Triangle
return base.Read (bmp, info);
}
+ internal static byte[] UnpackBitmap (Stream stream, int pack_type, int packed_size, int unpacked_size)
+ {
+ if (2 == pack_type)
+ {
+ using (var reader = new RleReader (stream, packed_size, unpacked_size))
+ {
+ reader.Unpack();
+ return reader.Data;
+ }
+ }
+ else if (0 == pack_type)
+ {
+ using (var reader = new LzssReader (stream, packed_size, unpacked_size))
+ {
+ reader.Unpack();
+ return reader.Data;
+ }
+ }
+ else if (1 == pack_type)
+ {
+ var bitmap = new byte[unpacked_size];
+ if (bitmap.Length != stream.Read (bitmap, 0, bitmap.Length))
+ throw new InvalidFormatException ("Unexpected end of file");
+ return bitmap;
+ }
+ else
+ throw new InvalidFormatException();
+ }
+
public override void Write (Stream file, ImageData image)
{
throw new System.NotImplementedException ("IafFormat.Write not implemented");
diff --git a/supported.html b/supported.html
index cc7536ba..6b06a7a5 100644
--- a/supported.html
+++ b/supported.html
@@ -122,9 +122,10 @@ Sweet Pool
Zoku Satsuriku no Django
| *.npa | - | Yes | Nitro+ | Steins;Gate |
-| *.pak | \002\000\000\000 \003\000\000\000 | No | Nitro+ |
+ |
| *.pak | \002\000\000\000 \003\000\000\000 | No | Nitro+ CoreMoreco |
Hanachirasu
Jingai Makyou
+Chibi Mama
|
*.nsa *.sar | - | Yes | NScripter |
Binary Pot
@@ -452,11 +453,13 @@ Gokudou no Hanayome
Knight Carnival!
Seal Princess
|
-| *.sud | - | No | Triangle |
+ |
| *.sud | - | No | Triangle |
Kourin Tenshi En Ciel Rena
Mamagoto
+Vampire Crusaders
|
| *.iaf | - | No |
+| *.cgf | - | No |
| *.bin+*.pak | hed | No | elf | Adult Video King |
*.hip *.hiz
| hip hiz | No |
*.gpk+*.gtb *.vpk+*.vtb | - | No | Black Cyc |
@@ -612,6 +615,7 @@ AstralAir no Shiroki Towa
|
| *.hzc | hzc1 | No |
| *.bin | ESC-ARC1 ESC-ARC2 | No | Escu:de |
Otome Renshin Prister
+Suisei Tenshi Primaveil Zwei
Wondering Repair!
|
| *.pac | - | No | Tmr-Hiro ADV System |
@@ -637,6 +641,7 @@ Ayakashi H
|
| *.arc | LINK3 | No | KaGuYa |
Dokidoki Onee-san
+Mahokoi ~Ecchi na Mahou de Koi x Koi Shichau~
|
| *.alp | AP-2 | No |
| *.anm | AN00 | No |