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