u8 * uncompressLZ77(const u8 *inBuf, u32 inLength, u32 * size) { if(!inBuf) return NULL; u8 *buffer = NULL; if (*((const u32 *)inBuf) != 0x4C5A3737 /*"LZ77"*/) return NULL; decompressLZ77content( (u8*)inBuf + 4, inLength - 4, &buffer, size); return buffer; }
u8* U8NandArchive::GetFileAllocated( const char *path, u32 *size ) const { //gprintf( "U8NandArchive::GetFileAllocated( %s )\n" ); if( !path || !fst ) { return NULL; } // find file int f = EntryFromPath( path, 0 ); if( f < 1 || f >= (int)fst[ 0 ].filelen ) { gprintf( "U8: \"%s\" wasn't found in the archive.\n", path ); return NULL; } if( fst[ f ].filetype ) { gprintf( "U8: \"%s\" is a folder\n", path ); return NULL; } // create a buffer u8* ret = (u8*)memalign( 32, RU( fst[ f ].filelen, 32 ) ); if( !ret ) { gprintf( "U8: out of memory\n" ); return NULL; } // seek and read if( ISFS_Seek( fd, dataOffset + fst[ f ].fileoffset, SEEK_SET ) != (s32)( dataOffset + fst[ f ].fileoffset ) || ISFS_Read( fd, ret, fst[ f ].filelen ) != (s32)fst[ f ].filelen ) { free( ret ); gprintf( "U8: error reading data from nand\n" ); gprintf( "fd: %i fst[ fd ].filelen: %08x\n", fd, fst[ f ].filelen ); return NULL; } u32 len = fst[ f ].filelen; u8* ret2; // determine if it needs to be decompressed if( IsAshCompressed( ret, len ) ) { // ASH0 ret2 = DecompressAsh( ret, len ); if( !ret2 ) { free( ret ); gprintf( "out of memory\n" ); return NULL; } free( ret ); } else if( isLZ77compressed( ret ) ) { // LZ77 with no magic word if( decompressLZ77content( ret, len, &ret2, &len ) ) { free( ret ); return NULL; } free( ret ); } else if( *(u32*)( ret ) == 0x4C5A3737 )// LZ77 { // LZ77 with a magic word if( decompressLZ77content( ret + 4, len - 4, &ret2, &len ) ) { free( ret ); return NULL; } free( ret ); } else { // already got what we are after ret2 = ret; } if( size ) { *size = len; } // flush the cache so if there are any textures in this data, it will be ready for the GX DCFlushRange( ret2, len ); return ret2; }
u8 *U8Archive::DecompressCopy( const u8 * stuff, u32 len, u32 *size ) const { // check for IMD5 header and skip it if( len > 0x40 && *(u32*)stuff == 0x494d4435 )// IMD5 { stuff += 0x20; len -= 0x20; } u8* ret = NULL; // determine if it needs to be decompressed if( IsAshCompressed( stuff, len ) ) { //u32 len2 = len; // ASH0 ret = DecompressAsh( stuff, len ); if( !ret ) { gprintf( "out of memory\n" ); return NULL; } } else if( (len > 8) && *(u32*)( stuff ) == 0x59617a30 )// Yaz0 { // Yaz0 with a magic word Yaz0_Header *header = (Yaz0_Header *) stuff; // set decompress length len = header->decompressed_size; // allocate memory ret = (u8*) memalign(32, ALIGN32(len)); if(!ret) { gprintf("out of memory\n"); return NULL; } // function can not fail at this point uncompressYaz0(stuff, ret, len); } else if( isLZ77compressed( stuff ) ) { // LZ77 with no magic word if( decompressLZ77content( stuff, len, &ret, &len ) ) { return NULL; } } else if( *(u32*)( stuff ) == 0x4C5A3737 )// LZ77 { // LZ77 with a magic word if( decompressLZ77content( stuff + 4, len - 4, &ret, &len ) ) { return NULL; } } else { // just copy the data out of the archive ret = (u8*)memalign( 32, ALIGN32( len ) ); if( !ret ) { gprintf( "out of memory\n" ); return NULL; } memcpy( ret, stuff, len ); } if( size ) { *size = len; } // flush the cache so if there are any textures in this data, it will be ready for the GX DCFlushRange( ret, len ); return ret; }
u8* U8Archive::GetFileAllocated( const char *path, u32 *size ) const { u32 len; const u8 *stuff = GetFile( path, &len ); if( !stuff ) { return NULL; } // check for IMD5 header and skip it if( len > 0x40 && *(u32*)stuff == 0x494d4435 )// IMD5 { stuff += 0x20; len -= 0x20; } u8* ret = NULL; // determine if it needs to be decompressed if( IsAshCompressed( stuff, len ) ) { //u32 len2 = len; // ASH0 ret = DecompressAsh( stuff, len ); if( !ret ) { gprintf( "out of memory\n" ); return NULL; } /* u8* ret2 = DecompressAsh2( stuff, len2 ); if( !ret2 ) { gprintf( "out of memory 2\n" ); return NULL; } if( len != len2 || memcmp( ret, ret2, len ) ) { gprintf( "doesn\'t match\n" ); } else { gprintf( "matches\n" ); } exit( 0 );*/ } else if( isLZ77compressed( stuff ) ) { // LZ77 with no magic word if( decompressLZ77content( stuff, len, &ret, &len ) ) { return NULL; } } else if( *(u32*)( stuff ) == 0x4C5A3737 )// LZ77 { // LZ77 with a magic word if( decompressLZ77content( stuff + 4, len - 4, &ret, &len ) ) { return NULL; } } else { // just copy the data out of the archive ret = (u8*)memalign( 32, len ); if( !ret ) { gprintf( "out of memory\n" ); return NULL; } memcpy( ret, stuff, len ); } if( size ) { *size = len; } // flush the cache so if there are any textures in this data, it will be ready for the GX DCFlushRange( ret, len ); return ret; }