Skip to content

Commit 93dfb35

Browse files
committed
(Rain): added cgd images decoder.
1 parent f536bfa commit 93dfb35

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

Legacy/Rain/ArcBIN.cs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
using System.ComponentModel.Composition;
2929
using System.IO;
3030
using System.Text.RegularExpressions;
31+
using System.Windows.Media;
3132
using GameRes.Compression;
3233

3334
namespace GameRes.Formats.Rain
@@ -88,5 +89,103 @@ public override Stream OpenEntry (ArcFile arc, Entry entry)
8889
lzss.Config.FrameInitPos = 0xFF0;
8990
return lzss;
9091
}
92+
93+
public override IImageDecoder OpenImage (ArcFile arc, Entry entry)
94+
{
95+
if (!entry.Name.HasExtension ("cgd"))
96+
return base.OpenImage (arc, entry);
97+
98+
var input = OpenEntry (arc, entry);
99+
return new CgdImageDecoder (new BinaryStream (input, entry.Name));
100+
}
101+
}
102+
103+
internal class CgdImageDecoder : BinaryImageDecoder
104+
{
105+
int m_data_length;
106+
int m_blocks_offset;
107+
int m_rgb16_offset;
108+
int m_rgb24_offset;
109+
110+
int m_blocks_w;
111+
int m_blocks_h;
112+
int m_stride;
113+
114+
public CgdImageDecoder (IBinaryStream input) : base (input)
115+
{
116+
var header = m_input.ReadBytes (0x2C);
117+
Info = new ImageMetaData {
118+
Width = header.ToUInt32 (4),
119+
Height = header.ToUInt32 (8),
120+
BPP = 24,
121+
};
122+
m_data_length = header.ToInt32 (0);
123+
m_blocks_offset = header.ToInt32 (0x20);
124+
m_rgb16_offset = header.ToInt32 (0x24);
125+
m_rgb24_offset = header.ToInt32 (0x28);
126+
m_blocks_w = (int)Info.Width / 8;
127+
m_blocks_h = (int)Info.Height / 8;
128+
m_stride = (int)Info.Width * 3;
129+
}
130+
131+
protected override ImageData GetImageData ()
132+
{
133+
int[] blocks;
134+
byte[] pixels;
135+
if (m_blocks_offset != 0)
136+
{
137+
blocks = new int[m_blocks_w * m_blocks_h * 2];
138+
for (int i = 0; i < blocks.Length; ++i)
139+
{
140+
blocks[i] = m_input.ReadInt32();
141+
}
142+
m_input.ReadBytes (m_rgb24_offset-m_rgb16_offset);
143+
pixels = UnpackBlocks (blocks);
144+
}
145+
else
146+
{
147+
m_input.ReadBytes (m_rgb24_offset-m_rgb16_offset);
148+
pixels = m_input.ReadBytes (m_data_length-m_rgb24_offset);
149+
}
150+
return ImageData.Create (Info, PixelFormats.Bgr24, null, pixels, m_stride);
151+
}
152+
153+
byte[] UnpackBlocks (int[] blocks)
154+
{
155+
var output = new byte[m_stride * (int)Info.Height];
156+
int i = 0;
157+
for (int y = 0; y < m_blocks_h; ++y)
158+
{
159+
int dst = y * 8 * m_stride;
160+
for (int x = 0; x < m_blocks_w; )
161+
{
162+
int count = (blocks[i] >> 8) & 0xFF;
163+
int row_length = 0;
164+
switch (blocks[i] >> 16)
165+
{
166+
case 0: row_length = 0; break;
167+
case 1: row_length = 24; break;
168+
case 2:
169+
case 3: row_length = 32; break;
170+
}
171+
for (int j = 0; j < count; ++j)
172+
{
173+
if ((blocks[i] >> 16) != 0)
174+
{
175+
m_input.Read (output, dst, row_length);
176+
dst += row_length;
177+
}
178+
i += 2;
179+
}
180+
if (row_length != 0)
181+
{
182+
m_input.Read (output, dst, 7 * count * row_length);
183+
dst += 7 * count * row_length;
184+
}
185+
x += count;
186+
}
187+
}
188+
return output;
189+
}
91190
}
92191
}

0 commit comments

Comments
 (0)