1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - MI - include
3 File: uncompress.h
4
5 Copyright 2003-2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2008-09-17#$
14 $Rev: 8556 $
15 $Author: okubata_ryoma $
16
17 *---------------------------------------------------------------------------*/
18
19 #ifndef NITRO_MI_UNCOMPRESS_H_
20 #define NITRO_MI_UNCOMPRESS_H_
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 #include <nitro/misc.h>
27 #include <nitro/types.h>
28
29
30 //---- Compression Types
31 typedef enum
32 {
33 MI_COMPRESSION_LZ = 0x10, // LZ77
34 MI_COMPRESSION_HUFFMAN = 0x20, // Huffman
35 MI_COMPRESSION_RL = 0x30, // Run Length
36 MI_COMPRESSION_DIFF = 0x80, // Differential filter
37
38 MI_COMPRESSION_TYPE_MASK = 0xf0,
39 MI_COMPRESSION_TYPE_EX_MASK = 0xff
40 }
41 MICompressionType;
42
43
44 //----------------------------------------------------------------
45 // Compressed Data Header
46 //
47 typedef struct
48 {
49 u32 compParam:4;
50 u32 compType:4;
51 u32 destSize:24;
52
53 }
54 MICompressionHeader;
55
56
57
58 //----------------------------------------------------------------
59 // Parameters for expanding bit compressed data
60 //
61 typedef struct
62 {
63 u16 srcNum; // Source data / Number of bytes
64 u16 srcBitNum:8; // Number of bits per one source data element
65 u16 destBitNum:8; // Number of bits per one destination data element
66 u32 destOffset:31; // Number to add to source data
67 u32 destOffset0_on:1; // Flag for whether to add an offset to 0 data.
68 }
69 MIUnpackBitsParam;
70
71
72 //======================================================================
73 // Expanding Compressed Data
74 //======================================================================
75
76 //----------------------------------------------------------------------
77 // Expanding Bit Compressed Data
78 //
79 //- Unpacks data padded with bits fixed to 0.
80 //- Align the destination address to a 4-byte boundary.
81 //
82 //Arguments:
83 // void *srcp: source address
84 // void *destp: destination address
85 // MIUnpackBitsParam *paramp: Address of MIUnpackBitsParam structure
86 //
87 //MIUnpackBitsParam Structure
88 // u16 srcNum: Number of bytes per source data element
89 // u8 srcBitNum: Number of bits per source data element
90 // u8 destBitNum: Number of bits per destination data element
91 // u32 destOffset:31: Offset number to add to source data.
92 // destOffset0_On:1: Flag for whether to add an offset to 0 data.
93 //
94 //- Return value: None
95 //----------------------------------------------------------------------
96
97 void MI_UnpackBits(const void *srcp, void *destp, MIUnpackBitsParam *paramp);
98
99
100 //----------------------------------------------------------------------
101 // 8-bit decompression of LZ77 compressed data
102 //
103 //* Expands LZ77-compressed data and writes it in 8-bit units.
104 //- Cannot decompress directly into VRAM
105 //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible.
106 //
107 //- Use 4-byte alignment for the source address.
108 //
109 //Arguments:
110 // void *srcp: source address
111 // void *destp: destination address
112 //
113 //- Data header
114 // u32 :4 : Reserved
115 // compType:4 Compression type( = 1)
116 // destSize:24 Data size after decompression
117 //
118 //- Flag data format
119 // u8 flags Compression/no compression flag
120 // (0, 1) = (not compressed, compressed)
121 //- Code data format (big endian)
122 // u16 length:4 Decompressed data length - 3 (only compress when the match length is 3 bytes or greater)
123 // offset:12 Match data offset - 1
124 //
125 //- Return value: None
126 //----------------------------------------------------------------------
127
128 void MI_UncompressLZ8(const void *srcp, void *destp);
129
130
131 //----------------------------------------------------------------------
132 // 16-bit decompression of LZ77 compressed data
133 //
134 //* Expands LZ77-compressed data and writes it in 16-bit units.
135 //* Although it can also expand in data TCM and main memory, it is slower than MI_UncompressLZ778().
136 //
137 //* For compressed data, search for a matching character string from a minimum of 2 bytes previous.
138 //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible.
139 //
140 //- Use 4-byte alignment for the source address.
141 //
142 //Arguments:
143 // void *srcp: source address
144 // void *destp: destination address
145 //
146 //- Data header
147 // u32 :4 : Reserved
148 // compType:4 Compression type( = 1)
149 // destSize:24 Data size after decompression
150 //
151 //- Flag data format
152 // u8 flags Compression/no compression flag
153 // (0, 1) = (not compressed, compressed)
154 //- Code data format (big endian)
155 // u16 length:4 Decompressed data length - 3 (only compress when the match length is 3 bytes or greater)
156 // offset:12 : Match data offset ( >= 2) - 1
157 //
158 //- Return value: None
159 //----------------------------------------------------------------------
160
161 void MI_UncompressLZ16(const void *srcp, void *destp);
162
163
164 //----------------------------------------------------------------------
165 // Decompression of Huffman compressed data
166 //
167 //- Decompresses Huffman compressed data, writing in 32-bit units.
168 //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible.
169 //
170 //- Use 4-byte alignment for the source address.
171 //
172 //Arguments:
173 // void *srcp: source address
174 // void *destp: destination address
175 //
176 //- Data header
177 // u32 bitSize:4 1 data bit size (Normally 4|8)
178 // compType:4 Compression type( = 2)
179 // destSize:24 Data size after decompression
180 //
181 //- Tree table
182 // u8 treeSize Tree table size/2 - 1
183 // TreeNodeData nodeRoot Root node
184 //
185 // TreeNodeData nodeLeft Root left node
186 // TreeNodeData nodeRight Root right node
187 //
188 // TreeNodeData nodeLeftLeft Left left node
189 // TreeNodeData nodeLeftRight Left right node
190 //
191 // TreeNodeData nodeRightLeft Right left node
192 // TreeNodeData nodeRightRight Right right node
193 //
194 // �E
195 // �E
196 //
197 // The compressed data itself follows
198 //
199 //- TreeNodeData structure
200 // u8 nodeNextOffset:6 : Offset to the next node data - 1 (2 byte units)
201 // rightEndFlag:1 Right node end flag
202 // leftEndzflag:1 Left node end flag
203 // When end flag is set, there is data in next node.
204 //
205 //
206 //- Return value: None
207 //----------------------------------------------------------------------
208
209 void MI_UncompressHuffman(const void *srcp, void *destp);
210
211
212 //----------------------------------------------------------------------
213 // 8-bit decompression of run-length compressed data
214 //
215 //- Decompresses run-length compressed data, writing in 8 bit units.
216 //- You cannot decompress directly to VRAM on a NITRO system.
217 //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible.
218 //
219 //- Use 4-byte alignment for the source address.
220 //
221 //Arguments:
222 // void *srcp: source address
223 // void *destp: destination address
224 //
225 //- Data header
226 // u32 :4 : Reserved
227 // compType:4 Compression type( = 3)
228 // destSize:24 Data size after decompression
229 //
230 //- Flag data format
231 // u8 length:7 Decompressed data length - 1 (When not compressed)
232 // Decompressed data length - 3 (only compress when the contiguous length is 3 bytes or greater)
233 // flag:1 (0, 1) = (not compressed, compressed)
234 //
235 //- Return value: None
236 //----------------------------------------------------------------------
237
238 void MI_UncompressRL8(const void *srcp, void *destp);
239
240
241 //----------------------------------------------------------------------
242 // 16-bit decompression of run-length compressed data
243 //
244 //- Decompresses run-length compressed data, writing in 16-bit units.
245 //- You can also decompress to data TCM and VRAM.
246 //- This is slower than MI_UncompressRL8() for decompression to main RAM.
247 //- This is faster than MI_UncompressRL8() for decompression to data TCM and VRAM.
248 //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible.
249 //
250 //- Use 4-byte alignment for the source address.
251 //
252 //Arguments:
253 // void *srcp: source address
254 // void *destp: destination address
255 //
256 //- Data header
257 // u32 :4 : Reserved
258 // compType:4 Compression type( = 3)
259 // destSize:24 Data size after decompression
260 //
261 //- Flag data format
262 // u8 length:7 Decompressed data length - 1 (When not compressed)
263 // Decompressed data length - 3 (only compress when the contiguous length is 3 bytes or greater)
264 // flag:1 (0, 1) = (not compressed, compressed)
265 //
266 //- Return value: None
267 //----------------------------------------------------------------------
268
269 void MI_UncompressRL16(const void *srcp, void *destp);
270
271
272 //----------------------------------------------------------------------
273 // 32-bit decompression of run-length compressed data
274 //
275 //- Decompresses run-length compressed data, writing in 32-bit units.
276 //- This is faster than MI_UncompressRL8() and MI_UncompressRL16().
277 //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible.
278 //
279 //- Use 4-byte alignment for the source address.
280 //
281 //Arguments:
282 // void *srcp: source address
283 // void *destp: destination address
284 //
285 //- Data header
286 // u32 :4 : Reserved
287 // compType:4 Compression type( = 3)
288 // destSize:24 Data size after decompression
289 //
290 //- Flag data format
291 // u8 length:7 Decompressed data length - 1 (When not compressed)
292 // Decompressed data length - 3 (only compress when the contiguous length is 3 bytes or greater)
293 // flag:1 (0, 1) = (not compressed, compressed)
294 //
295 //- Return value: None
296 //----------------------------------------------------------------------
297
298 void MI_UncompressRL32(register const void *srcp,register void *destp);
299
300
301 //----------------------------------------------------------------------
302 // 8-bit decompression to restore differential filter conversion.
303 //
304 //- Restores a differential filter, writing in 8-bit units.
305 //- You cannot decompress directly to VRAM on a NITRO system.
306 //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible.
307 //
308 //- Use 4-byte alignment for the source address.
309 //
310 //Arguments:
311 // void *srcp: source address
312 // void *destp: destination address
313 //
314 //- Data header
315 // u32 :4 : Bit size of unit
316 // compType:4 Compression type( = 3)
317 // destSize:24 Data size after decompression
318 //
319 //- Return value: None
320 //----------------------------------------------------------------------
321
322 void MI_UnfilterDiff8(const void *srcp, void *destp);
323
324
325 //----------------------------------------------------------------------
326 // 16-bit decompression to restore differential filter conversion.
327 //
328 //- Restores a differential filter, writing in 16-bit units.
329 //- You can also decompress to data TCM and VRAM.
330 //- This is faster than MI_UnfilterDiff16().
331 //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible.
332 //
333 //- Use 4-byte alignment for the source address.
334 //
335 //Arguments:
336 // void *srcp: source address
337 // void *destp: destination address
338 //
339 //- Data header
340 // u32 :4 : Bit size of unit
341 // compType:4 Compression type( = 3)
342 // destSize:24 Data size after decompression
343 //
344 //- Return value: None
345 //----------------------------------------------------------------------
346
347 void MI_UnfilterDiff16(const void *srcp, void *destp);
348
349 //----------------------------------------------------------------------
350 // 32-bit decompression to restore differential filter conversion.
351 //
352 //- Restores a differential filter, writing in 32-bit units.
353 //- You can also decompress to data TCM and VRAM.
354 // This is faster than MI_Uncompress8().//----
355 //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible.
356 //
357 //- Use 4-byte alignment for the source address.
358 //
359 //Arguments:
360 // void *srcp: source address
361 // void *destp: destination address
362 //
363 //- Data header
364 // u32 :4 : Bit size of unit
365 // compType:4 Compression type( = 3)
366 // destSize:24 Data size after decompression
367 //
368 //- Return value: None
369 //----------------------------------------------------------------------
370
371 void MI_UnfilterDiff32(register const void *srcp,register void *destp);
372
373
374 //----------------------------------------------------------------------
375 // 8-bit decompression for differential filter conversion
376 //
377 //- Runs differential filter conversion and writes data 8 bits at a time.
378 //- You cannot decompress directly to VRAM on a NITRO system.
379 //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible.
380 //
381 //- Use 4-byte alignment for the source address.
382 //
383 //Arguments:
384 // void *srcp: source address
385 // void *destp: destination address
386 // u32 size Source size
387 // BOOL bitsize Differential size (TRUE: 16-bit, FALSE: 8-bit)
388 //
389 //- Data header
390 // u32 :4 : Bit size of unit
391 // compType:4 Compression type( = 3)
392 // destSize:24 Data size after decompression
393 //
394 //- Return value: None
395 //----------------------------------------------------------------------
396
397 void MI_FilterDiff8(register const void *srcp, register void *destp, register u32 size, register BOOL bitsize);
398
399
400 //----------------------------------------------------------------------
401 // 16-bit decompression for differential filter conversion
402 //
403 //- Runs differential filter conversion and writes data 16 bits at a time.
404 //- You can also decompress to data TCM and VRAM.
405 //- This is faster than MI_FilterDiff8().
406 //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible.
407 //
408 //- Use 4-byte alignment for the source address.
409 //
410 //Arguments:
411 // void *srcp: source address
412 // void *destp: destination address
413 // u32 size Source size
414 // BOOL bitsize Differential size (TRUE: 16-bit, FALSE: 8-bit)
415 //
416 //- Data header
417 // u32 :4 : Bit size of unit
418 // compType:4 Compression type( = 3)
419 // destSize:24 Data size after decompression
420 //
421 //- Return value: None
422 //----------------------------------------------------------------------
423
424 void MI_FilterDiff16(register const void *srcp, register void *destp, register u32 size, register BOOL bitsize);
425
426
427 //----------------------------------------------------------------------
428 // 32-bit decompression for differential filter conversion
429 //
430 //- Runs differential filter conversion and writes data 32 bits at a time.
431 //- This is faster than MI_FilterDiff16().
432 //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible.
433 //
434 //- Use 4-byte alignment for the source address.
435 //
436 //Arguments:
437 // void *srcp: source address
438 // void *destp: destination address
439 // u32 size Source size
440 // BOOL bitsize Differential size (TRUE: 16-bit, FALSE: 8-bit)
441 //
442 //- Data header
443 // u32 :4 : Bit size of unit
444 // compType:4 Compression type( = 3)
445 // destSize:24 Data size after decompression
446 //
447 //- Return value: None
448 //----------------------------------------------------------------------
449
450 void MI_FilterDiff32(register const void *srcp, register void *destp, register u32 size, register BOOL bitsize);
451
452
453 //================================================================================
454 /*---------------------------------------------------------------------------*
455 Name: MI_GetUncompressedSize
456
457 Description: Gets data size after uncompressing.
458 This function can be used for all compression types
459 (LZ8, LZ16, Huffman, RL8, RL16)
460
461 Arguments: srcp: Compressed data address
462
463 Returns: size
464 *---------------------------------------------------------------------------*/
MI_GetUncompressedSize(const void * srcp)465 static inline u32 MI_GetUncompressedSize(const void *srcp)
466 {
467 return (*(u32 *)srcp >> 8);
468 }
469
470 /*---------------------------------------------------------------------------*
471 Name: MI_GetCompressionType
472
473 Description: Gets compression type from compressed data.
474
475 Arguments: srcp: Compressed data address
476
477 Returns: Compression type.
478 MI_COMPREESION_LZ: mean compressed by LZ77
479 MI_COMPREESION_HUFFMAN: mean compressed by Huffman
480 MI_COMPREESION_RL: mean compressed by Run Length
481 MI_COMPRESSION_DIFF: mean converted by Differential filter
482 *---------------------------------------------------------------------------*/
MI_GetCompressionType(const void * srcp)483 static inline MICompressionType MI_GetCompressionType(const void *srcp)
484 {
485 return (MICompressionType)(*(u32 *)srcp & MI_COMPRESSION_TYPE_MASK);
486 }
487
488
489
490 /*---------------------------------------------------------------------------*
491 Name: MIi_UncompressBackward
492
493 Description: Uncompress special archive for module compression
494
495 Arguments: bottom = Bottom address of packed archive + 1
496 bottom[-12] = offset for top of compressed data
497 inp_top = bottom + bottom[-12]
498 bottom[ -8] = offset for bottom of compressed data
499 inp = bottom + bottom[ -8]
500 bottom[ -4] = offset for bottom of original data
501 outp = bottom + bottom[ -4]
502
503 typedef struct
504 {
505 int bufferTop;
506 int compressBottom;
507 int originalBottom;
508 } CompFooter;
509
510 Returns: None.
511 *---------------------------------------------------------------------------*/
512 // !!!! Coded in libraries/init/ARM9/crt0.c
513 void MIi_UncompressBackward(void *bottom);
514
515 #ifdef __cplusplus
516 } /* extern "C" */
517 #endif
518
519 /* NITRO_MI_UNCOMPRESS_H_ */
520 #endif
521