/*---------------------------------------------------------------------------* Project: TwlSDK - MI - include File: uncompress.h Copyright 2003-2008 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Date:: 2008-09-17#$ $Rev: 8556 $ $Author: okubata_ryoma $ *---------------------------------------------------------------------------*/ #ifndef NITRO_MI_UNCOMPRESS_H_ #define NITRO_MI_UNCOMPRESS_H_ #ifdef __cplusplus extern "C" { #endif #include #include //---- Compression Types typedef enum { MI_COMPRESSION_LZ = 0x10, // LZ77 MI_COMPRESSION_HUFFMAN = 0x20, // Huffman MI_COMPRESSION_RL = 0x30, // Run Length MI_COMPRESSION_DIFF = 0x80, // Differential filter MI_COMPRESSION_TYPE_MASK = 0xf0, MI_COMPRESSION_TYPE_EX_MASK = 0xff } MICompressionType; //---------------------------------------------------------------- // Compressed Data Header // typedef struct { u32 compParam:4; u32 compType:4; u32 destSize:24; } MICompressionHeader; //---------------------------------------------------------------- // Parameters for expanding bit compressed data // typedef struct { u16 srcNum; // Source data / Number of bytes u16 srcBitNum:8; // Number of bits per one source data element u16 destBitNum:8; // Number of bits per one destination data element u32 destOffset:31; // Number to add to source data u32 destOffset0_on:1; // Flag for whether to add an offset to 0 data. } MIUnpackBitsParam; //====================================================================== // Expanding Compressed Data //====================================================================== //---------------------------------------------------------------------- // Expanding Bit Compressed Data // //- Unpacks data padded with bits fixed to 0. //- Align the destination address to a 4-byte boundary. // //Arguments: // void *srcp: source address // void *destp: destination address // MIUnpackBitsParam *paramp: Address of MIUnpackBitsParam structure // //MIUnpackBitsParam Structure // u16 srcNum: Number of bytes per source data element // u8 srcBitNum: Number of bits per source data element // u8 destBitNum: Number of bits per destination data element // u32 destOffset:31: Offset number to add to source data. // destOffset0_On:1: Flag for whether to add an offset to 0 data. // //- Return value: None //---------------------------------------------------------------------- void MI_UnpackBits(const void *srcp, void *destp, MIUnpackBitsParam *paramp); //---------------------------------------------------------------------- // 8-bit decompression of LZ77 compressed data // //* Expands LZ77-compressed data and writes it in 8-bit units. //- Cannot decompress directly into VRAM //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible. // //- Use 4-byte alignment for the source address. // //Arguments: // void *srcp: source address // void *destp: destination address // //- Data header // u32 :4 : Reserved // compType:4 Compression type( = 1) // destSize:24 Data size after decompression // //- Flag data format // u8 flags Compression/no compression flag // (0, 1) = (not compressed, compressed) //- Code data format (big endian) // u16 length:4 Decompressed data length - 3 (only compress when the match length is 3 bytes or greater) // offset:12 Match data offset - 1 // //- Return value: None //---------------------------------------------------------------------- void MI_UncompressLZ8(const void *srcp, void *destp); //---------------------------------------------------------------------- // 16-bit decompression of LZ77 compressed data // //* Expands LZ77-compressed data and writes it in 16-bit units. //* Although it can also expand in data TCM and main memory, it is slower than MI_UncompressLZ778(). // //* For compressed data, search for a matching character string from a minimum of 2 bytes previous. //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible. // //- Use 4-byte alignment for the source address. // //Arguments: // void *srcp: source address // void *destp: destination address // //- Data header // u32 :4 : Reserved // compType:4 Compression type( = 1) // destSize:24 Data size after decompression // //- Flag data format // u8 flags Compression/no compression flag // (0, 1) = (not compressed, compressed) //- Code data format (big endian) // u16 length:4 Decompressed data length - 3 (only compress when the match length is 3 bytes or greater) // offset:12 : Match data offset ( >= 2) - 1 // //- Return value: None //---------------------------------------------------------------------- void MI_UncompressLZ16(const void *srcp, void *destp); //---------------------------------------------------------------------- // Decompression of Huffman compressed data // //- Decompresses Huffman compressed data, writing in 32-bit units. //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible. // //- Use 4-byte alignment for the source address. // //Arguments: // void *srcp: source address // void *destp: destination address // //- Data header // u32 bitSize:4 1 data bit size (Normally 4|8) // compType:4 Compression type( = 2) // destSize:24 Data size after decompression // //- Tree table // u8 treeSize Tree table size/2 - 1 // TreeNodeData nodeRoot Root node // // TreeNodeData nodeLeft Root left node // TreeNodeData nodeRight Root right node // // TreeNodeData nodeLeftLeft Left left node // TreeNodeData nodeLeftRight Left right node // // TreeNodeData nodeRightLeft Right left node // TreeNodeData nodeRightRight Right right node // // E // E // // The compressed data itself follows // //- TreeNodeData structure // u8 nodeNextOffset:6 : Offset to the next node data - 1 (2 byte units) // rightEndFlag:1 Right node end flag // leftEndzflag:1 Left node end flag // When end flag is set, there is data in next node. // // //- Return value: None //---------------------------------------------------------------------- void MI_UncompressHuffman(const void *srcp, void *destp); //---------------------------------------------------------------------- // 8-bit decompression of run-length compressed data // //- Decompresses run-length compressed data, writing in 8 bit units. //- You cannot decompress directly to VRAM on a NITRO system. //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible. // //- Use 4-byte alignment for the source address. // //Arguments: // void *srcp: source address // void *destp: destination address // //- Data header // u32 :4 : Reserved // compType:4 Compression type( = 3) // destSize:24 Data size after decompression // //- Flag data format // u8 length:7 Decompressed data length - 1 (When not compressed) // Decompressed data length - 3 (only compress when the contiguous length is 3 bytes or greater) // flag:1 (0, 1) = (not compressed, compressed) // //- Return value: None //---------------------------------------------------------------------- void MI_UncompressRL8(const void *srcp, void *destp); //---------------------------------------------------------------------- // 16-bit decompression of run-length compressed data // //- Decompresses run-length compressed data, writing in 16-bit units. //- You can also decompress to data TCM and VRAM. //- This is slower than MI_UncompressRL8() for decompression to main RAM. //- This is faster than MI_UncompressRL8() for decompression to data TCM and VRAM. //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible. // //- Use 4-byte alignment for the source address. // //Arguments: // void *srcp: source address // void *destp: destination address // //- Data header // u32 :4 : Reserved // compType:4 Compression type( = 3) // destSize:24 Data size after decompression // //- Flag data format // u8 length:7 Decompressed data length - 1 (When not compressed) // Decompressed data length - 3 (only compress when the contiguous length is 3 bytes or greater) // flag:1 (0, 1) = (not compressed, compressed) // //- Return value: None //---------------------------------------------------------------------- void MI_UncompressRL16(const void *srcp, void *destp); //---------------------------------------------------------------------- // 32-bit decompression of run-length compressed data // //- Decompresses run-length compressed data, writing in 32-bit units. //- This is faster than MI_UncompressRL8() and MI_UncompressRL16(). //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible. // //- Use 4-byte alignment for the source address. // //Arguments: // void *srcp: source address // void *destp: destination address // //- Data header // u32 :4 : Reserved // compType:4 Compression type( = 3) // destSize:24 Data size after decompression // //- Flag data format // u8 length:7 Decompressed data length - 1 (When not compressed) // Decompressed data length - 3 (only compress when the contiguous length is 3 bytes or greater) // flag:1 (0, 1) = (not compressed, compressed) // //- Return value: None //---------------------------------------------------------------------- void MI_UncompressRL32(register const void *srcp,register void *destp); //---------------------------------------------------------------------- // 8-bit decompression to restore differential filter conversion. // //- Restores a differential filter, writing in 8-bit units. //- You cannot decompress directly to VRAM on a NITRO system. //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible. // //- Use 4-byte alignment for the source address. // //Arguments: // void *srcp: source address // void *destp: destination address // //- Data header // u32 :4 : Bit size of unit // compType:4 Compression type( = 3) // destSize:24 Data size after decompression // //- Return value: None //---------------------------------------------------------------------- void MI_UnfilterDiff8(const void *srcp, void *destp); //---------------------------------------------------------------------- // 16-bit decompression to restore differential filter conversion. // //- Restores a differential filter, writing in 16-bit units. //- You can also decompress to data TCM and VRAM. //- This is faster than MI_UnfilterDiff16(). //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible. // //- Use 4-byte alignment for the source address. // //Arguments: // void *srcp: source address // void *destp: destination address // //- Data header // u32 :4 : Bit size of unit // compType:4 Compression type( = 3) // destSize:24 Data size after decompression // //- Return value: None //---------------------------------------------------------------------- void MI_UnfilterDiff16(const void *srcp, void *destp); //---------------------------------------------------------------------- // 32-bit decompression to restore differential filter conversion. // //- Restores a differential filter, writing in 32-bit units. //- You can also decompress to data TCM and VRAM. // This is faster than MI_Uncompress8().//---- //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible. // //- Use 4-byte alignment for the source address. // //Arguments: // void *srcp: source address // void *destp: destination address // //- Data header // u32 :4 : Bit size of unit // compType:4 Compression type( = 3) // destSize:24 Data size after decompression // //- Return value: None //---------------------------------------------------------------------- void MI_UnfilterDiff32(register const void *srcp,register void *destp); //---------------------------------------------------------------------- // 8-bit decompression for differential filter conversion // //- Runs differential filter conversion and writes data 8 bits at a time. //- You cannot decompress directly to VRAM on a NITRO system. //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible. // //- Use 4-byte alignment for the source address. // //Arguments: // void *srcp: source address // void *destp: destination address // u32 size Source size // BOOL bitsize Differential size (TRUE: 16-bit, FALSE: 8-bit) // //- Data header // u32 :4 : Bit size of unit // compType:4 Compression type( = 3) // destSize:24 Data size after decompression // //- Return value: None //---------------------------------------------------------------------- void MI_FilterDiff8(register const void *srcp, register void *destp, register u32 size, register BOOL bitsize); //---------------------------------------------------------------------- // 16-bit decompression for differential filter conversion // //- Runs differential filter conversion and writes data 16 bits at a time. //- You can also decompress to data TCM and VRAM. //- This is faster than MI_FilterDiff8(). //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible. // //- Use 4-byte alignment for the source address. // //Arguments: // void *srcp: source address // void *destp: destination address // u32 size Source size // BOOL bitsize Differential size (TRUE: 16-bit, FALSE: 8-bit) // //- Data header // u32 :4 : Bit size of unit // compType:4 Compression type( = 3) // destSize:24 Data size after decompression // //- Return value: None //---------------------------------------------------------------------- void MI_FilterDiff16(register const void *srcp, register void *destp, register u32 size, register BOOL bitsize); //---------------------------------------------------------------------- // 32-bit decompression for differential filter conversion // //- Runs differential filter conversion and writes data 32 bits at a time. //- This is faster than MI_FilterDiff16(). //- If the compressed data size was not a multiple of four, adjust by padding with 0s as much as possible. // //- Use 4-byte alignment for the source address. // //Arguments: // void *srcp: source address // void *destp: destination address // u32 size Source size // BOOL bitsize Differential size (TRUE: 16-bit, FALSE: 8-bit) // //- Data header // u32 :4 : Bit size of unit // compType:4 Compression type( = 3) // destSize:24 Data size after decompression // //- Return value: None //---------------------------------------------------------------------- void MI_FilterDiff32(register const void *srcp, register void *destp, register u32 size, register BOOL bitsize); //================================================================================ /*---------------------------------------------------------------------------* Name: MI_GetUncompressedSize Description: Gets data size after uncompressing. This function can be used for all compression types (LZ8, LZ16, Huffman, RL8, RL16) Arguments: srcp: Compressed data address Returns: size *---------------------------------------------------------------------------*/ static inline u32 MI_GetUncompressedSize(const void *srcp) { return (*(u32 *)srcp >> 8); } /*---------------------------------------------------------------------------* Name: MI_GetCompressionType Description: Gets compression type from compressed data. Arguments: srcp: Compressed data address Returns: Compression type. MI_COMPREESION_LZ: mean compressed by LZ77 MI_COMPREESION_HUFFMAN: mean compressed by Huffman MI_COMPREESION_RL: mean compressed by Run Length MI_COMPRESSION_DIFF: mean converted by Differential filter *---------------------------------------------------------------------------*/ static inline MICompressionType MI_GetCompressionType(const void *srcp) { return (MICompressionType)(*(u32 *)srcp & MI_COMPRESSION_TYPE_MASK); } /*---------------------------------------------------------------------------* Name: MIi_UncompressBackward Description: Uncompress special archive for module compression Arguments: bottom = Bottom address of packed archive + 1 bottom[-12] = offset for top of compressed data inp_top = bottom + bottom[-12] bottom[ -8] = offset for bottom of compressed data inp = bottom + bottom[ -8] bottom[ -4] = offset for bottom of original data outp = bottom + bottom[ -4] typedef struct { int bufferTop; int compressBottom; int originalBottom; } CompFooter; Returns: None. *---------------------------------------------------------------------------*/ // !!!! Coded in libraries/init/ARM9/crt0.c void MIi_UncompressBackward(void *bottom); #ifdef __cplusplus } /* extern "C" */ #endif /* NITRO_MI_UNCOMPRESS_H_ */ #endif