BrawlCrate v0.41
Wii File Editor
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | List of all members
BrawlLib.Wii.Compression.RunLength Class Reference

Public Member Functions

int Compress (VoidPtr srcAddr, int srcLen, Stream outStream, IProgressTracker progress, int type)
 
Parameters
type0 is YAZ0, 1 is YAY0, anything else is CompressionHeader
More...
 

Static Public Member Functions

static int CompactYAZ0 (VoidPtr srcAddr, int srcLen, Stream outStream, ResourceNode r)
 
static int CompactYAY0 (VoidPtr srcAddr, int srcLen, Stream outStream, ResourceNode r)
 
static int Compact (VoidPtr srcAddr, int srcLen, Stream outStream, ResourceNode r)
 
static void ExpandYAZ0 (YAZ0 *header, VoidPtr dstAddress, int dstLen)
 
static void ExpandYAY0 (YAY0 *header, VoidPtr dstAddress, int dstLen)
 
static void Expand (CompressionHeader *header, VoidPtr dstAddress, int dstLen)
 
static void Expand (VoidPtr srcAddress, VoidPtr dstAddress, int dstLen)
 Expands data at an address using default RunLength compression. Do not use this for YAY0 data, as it uses codes and counts at their own addresses. More...
 
static void Expand (ref byte *srcPtr, ref byte *codes, ref byte *counts, byte *dstPtr, int dstLen)
 

Member Function Documentation

◆ Compact()

static int BrawlLib.Wii.Compression.RunLength.Compact ( VoidPtr  srcAddr,
int  srcLen,
Stream  outStream,
ResourceNode  r 
)
inlinestatic
322 {
323 using (ProgressWindow prog = new ProgressWindow(r.RootNode._mainForm, "RunLength",
324 $"Compressing {r.Name}, please wait...", false))
325 {
326 return new RunLength().Compress(srcAddr, srcLen, outStream, prog, 2);
327 }
328 }
Definition: ProgressWindow.cs:8
ResourceNode RootNode
Definition: ResourceNode.cs:175
Form _mainForm
Definition: ResourceNode.cs:130

◆ CompactYAY0()

static int BrawlLib.Wii.Compression.RunLength.CompactYAY0 ( VoidPtr  srcAddr,
int  srcLen,
Stream  outStream,
ResourceNode  r 
)
inlinestatic
313 {
314 using (ProgressWindow prog = new ProgressWindow(r.RootNode._mainForm, "RunLength - YAY0",
315 $"Compressing {r.Name}, please wait...", false))
316 {
317 return new RunLength().Compress(srcAddr, srcLen, outStream, prog, 1);
318 }
319 }

◆ CompactYAZ0()

static int BrawlLib.Wii.Compression.RunLength.CompactYAZ0 ( VoidPtr  srcAddr,
int  srcLen,
Stream  outStream,
ResourceNode  r 
)
inlinestatic
304 {
305 using (ProgressWindow prog = new ProgressWindow(r.RootNode._mainForm, "RunLength - YAZ0",
306 $"Compressing {r.Name}, please wait...", false))
307 {
308 return new RunLength().Compress(srcAddr, srcLen, outStream, prog, 0);
309 }
310 }

◆ Compress()

int BrawlLib.Wii.Compression.RunLength.Compress ( VoidPtr  srcAddr,
int  srcLen,
Stream  outStream,
IProgressTracker  progress,
int  type 
)
inline

Parameters
type0 is YAZ0, 1 is YAY0, anything else is CompressionHeader

96 {
97 _pSrc = (byte*) srcAddr;
98 _sourceLen = srcLen;
99
100 int chunkCount = (int) Math.Ceiling((double) srcLen / _threadChunk);
101
102 progress?.Begin(0, srcLen, 0);
103
104 _contractions = new List<Contraction>[chunkCount];
105
106 bool YAY0Comp = type == 1;
107
108 if (type == 0)
109 {
110 YAZ0 header = new YAZ0
111 {
112 _tag = YAZ0.Tag,
113 _unCompDataLen = (uint) _sourceLen
114 };
115 outStream.Write(&header, YAZ0.Size);
116 }
117 else if (type == 1)
118 {
119 //Don't write YAY0 header yet.
120 //Collect all compression data first
121 }
122 else
123 {
124 CompressionHeader header = new CompressionHeader
125 {
126 Algorithm = CompressionType.RunLength,
127 ExpandedSize = (uint) _sourceLen
128 };
129 outStream.Write(&header, 4 + (header.LargeSize ? 4 : 0));
130 }
131
132 ParallelLoopResult result = Parallel.For(0, chunkCount, FindContractions);
133
134 while (!result.IsCompleted)
135 {
136 Thread.Sleep(100);
137 }
138
139 List<Contraction> fullContractions;
140 int codeBits, current;
141 byte codeByte;
142 //byte[] temp;
143 int lastUpdate = srcLen;
144
145 fullContractions = new List<Contraction>();
146 for (int i = 0; i < _contractions.Length; i++)
147 {
148 fullContractions.AddRange(_contractions[i]);
149 _contractions[i].Clear();
150 _contractions[i] = null;
151 }
152
153 _contractions = null;
154
155 //temp = new byte[3 * 8];
156 codeBits = 0;
157 codeByte = 0;
158 current = 0;
159
160 List<byte> tempCounts = new List<byte>();
161 List<byte> tempData = new List<byte>();
162 List<byte> codes = new List<byte>();
163 List<List<byte>> counts = new List<List<byte>>();
164 List<List<byte>> data = new List<List<byte>>();
165
166 for (int i = 0; i < srcLen;)
167 {
168 if (codeBits == 8)
169 {
170 codes.Add(codeByte);
171 counts.Add(tempCounts);
172 data.Add(tempData);
173
174 tempCounts = new List<byte>();
175 tempData = new List<byte>();
176
177 codeBits = 0;
178 codeByte = 0;
179 }
180
181 if (current < fullContractions.Count && fullContractions[current].Location == i)
182 {
183 if (fullContractions[current].Size >= 0x12)
184 {
185 byte
186 b1 = (byte) (fullContractions[current].Offset >> 8),
187 b2 = (byte) (fullContractions[current].Offset & 0xFF);
188
189 if (YAY0Comp)
190 {
191 tempCounts.Add(b1);
192 tempCounts.Add(b2);
193 }
194 else
195 {
196 tempData.Add(b1);
197 tempData.Add(b2);
198 }
199
200 tempData.Add((byte) (fullContractions[current].Size - 0x12));
201 }
202 else
203 {
204 byte
205 b1 = (byte) ((fullContractions[current].Offset >> 8) |
206 ((fullContractions[current].Size - 2) << 4)),
207 b2 = (byte) (fullContractions[current].Offset & 0xFF);
208
209 if (YAY0Comp)
210 {
211 tempCounts.Add(b1);
212 tempCounts.Add(b2);
213 }
214 else
215 {
216 tempData.Add(b1);
217 tempData.Add(b2);
218 }
219 }
220
221 i += fullContractions[current++].Size;
222
223 while (current < fullContractions.Count && fullContractions[current].Location < i)
224 {
225 current++;
226 }
227 }
228 else
229 {
230 codeByte |= (byte) (1 << (7 - codeBits));
231 tempData.Add(_pSrc[i++]);
232 }
233
234 codeBits++;
235
236 if (progress != null)
237 {
238 if (i % 0x4000 == 0)
239 {
240 progress.Update(i);
241 }
242 }
243 }
244
245 codes.Add(codeByte);
246 counts.Add(tempCounts);
247 data.Add(tempData);
248
249 if (YAY0Comp)
250 {
251 //Write header
252 YAY0 header = new YAY0
253 {
254 _tag = YAY0.Tag,
255 _unCompDataLen = (uint) _sourceLen
256 };
257 uint offset = 0x10 + (uint) codes.Count;
258 header._countOffset = offset;
259 foreach (List<byte> list in counts)
260 {
261 offset += (uint) list.Count;
262 }
263
264 header._dataOffset = offset;
265 outStream.Write(&header, YAY0.Size);
266
267 //Write codes
268 foreach (byte c in codes)
269 {
270 outStream.WriteByte(c);
271 }
272
273 //Write counts
274 foreach (List<byte> list in counts)
275 {
276 outStream.Write(list.ToArray(), 0, list.Count);
277 }
278
279 //Write data
280 foreach (List<byte> list in data)
281 {
282 outStream.Write(list.ToArray(), 0, list.Count);
283 }
284 }
285 else
286 {
287 for (int i = 0; i < codes.Count; i++)
288 {
289 //Write code
290 outStream.WriteByte(codes[i]);
291 //Write data
292 outStream.Write(data[i].ToArray(), 0, data[i].Count);
293 }
294 }
295
296 outStream.Flush();
297
298 progress?.Finish();
299
300 return (int) outStream.Length;
301 }
void Begin(float min, float max, float current)
CompressionType
Definition: CompressionHeader.cs:9

◆ Expand() [1/3]

static void BrawlLib.Wii.Compression.RunLength.Expand ( CompressionHeader header,
VoidPtr  dstAddress,
int  dstLen 
)
inlinestatic
346 {
347 Expand(header->Data, dstAddress, dstLen);
348 }
static void Expand(CompressionHeader *header, VoidPtr dstAddress, int dstLen)
Definition: RunLength.cs:345

◆ Expand() [2/3]

static void BrawlLib.Wii.Compression.RunLength.Expand ( ref byte *  srcPtr,
ref byte *  codes,
ref byte *  counts,
byte *  dstPtr,
int  dstLen 
)
inlinestatic
362 {
363 for (byte* ceiling = dstPtr + dstLen; dstPtr < ceiling;)
364 {
365 for (byte control = *codes++, bit = 8; bit-- != 0 && dstPtr != ceiling;)
366 {
367 if ((control & (1 << bit)) != 0)
368 {
369 *dstPtr++ = *srcPtr++;
370 }
371 else
372 {
373 for (int b1 = *counts++,
374 b2 = *counts++,
375 offset = (((b1 & 0xF) << 8) | b2) + 2,
376 temp = (b1 >> 4) & 0xF,
377 num = temp == 0 ? *srcPtr++ + 0x12 : temp + 2;
378 num-- > 0 && dstPtr != ceiling;
379 *dstPtr++ = dstPtr[-offset])
380 {
381 ;
382 }
383 }
384 }
385 }
386 }

◆ Expand() [3/3]

static void BrawlLib.Wii.Compression.RunLength.Expand ( VoidPtr  srcAddress,
VoidPtr  dstAddress,
int  dstLen 
)
inlinestatic

Expands data at an address using default RunLength compression. Do not use this for YAY0 data, as it uses codes and counts at their own addresses.

355 {
356 //Use this for reference in the function
357 byte* srcData = (byte*) srcAddress;
358 Expand(ref srcData, ref srcData, ref srcData, (byte*) dstAddress, dstLen);
359 }

◆ ExpandYAY0()

static void BrawlLib.Wii.Compression.RunLength.ExpandYAY0 ( YAY0 header,
VoidPtr  dstAddress,
int  dstLen 
)
inlinestatic
336 {
337 byte*
338 codes = (byte*) header + 0x10,
339 counts = (byte*) header + header->_countOffset,
340 srcPtr = (byte*) header + header->_dataOffset;
341
342 Expand(ref srcPtr, ref codes, ref counts, (byte*) dstAddress, dstLen);
343 }

◆ ExpandYAZ0()

static void BrawlLib.Wii.Compression.RunLength.ExpandYAZ0 ( YAZ0 header,
VoidPtr  dstAddress,
int  dstLen 
)
inlinestatic
331 {
332 Expand(header->Data, dstAddress, dstLen);
333 }

The documentation for this class was generated from the following file: